Conversation
|
So this is very interesting. I have a WIP solution to using other strategies, it does however completely refactor your solution. Do you mind taking a look? I decided to move away from having a shared-cursor and instead storing the client_ids that are part of the shared group. It then picks clients based on round-robin (not really a perfect solution but working). It would be really easy to add other strategies in my solution aswell, such as sticky, random etc. I am not quite sure I fully understand how everything works in the router so if you see anything that looks weird that very well might be the case. Here is my branch for this. https://github.com/Nickztar/rumqtt/tree/shared-subscription |
|
Hey @Nickztar , thanks for the contribution. I just glanced over your solution, and have a question, is it really round-robin? I did previously ( when i was experimenting ) use HashSet and a "state" to indicate current one and which client to send next. But here we also have to consider cases where client can get disconnected without getting message, so are we able to send the same message to some other client in the group? Will go over your solution ASAP. Thank you! 🚀 |
|
Oh yea, that might be correct. Will have to keep testing then but this feels a lot more round-robin. Can also easily be changed to a ordered vec or something. |
|
update: I went over the solution, and here are some observations/suggestions:
Thank you for taking the initiative to add other strategies @Nickztar 💯 |
|
Great thoughts! As for the DataRequest point, I could not get any duplicates to schedule. Haven't done any large tests but in my testing I got round-robin working. The FilterCaughtUp feels like a hack, but does make sense in that we have "caught up" to what should be sent for that client. |
That's a good thing, now I gotta try it myself and figure out the why behind it 😆 .
Trust me, you don't wanna know what kind of hacks I tried to get round-robin working ( ofc, they didn't work well haha ). But as you mentioned, setting status to "caught up" do make sense, so I won't call it a hack! |
|
As for why DataRequest works, cursor is updated before we actually determine that we arent the current client in a shared subscription. (alteast if my understanding of it is correct). |
|
Ooh, I thought we were doing that check at the very beginning of function, before doing anything. My bad 😅 |
|
Thinking of which, do you think doing that check as first thing in function and using shared cursor will be better? That way we will avoid multiple reads from datalogs, which looks expensive than using shared cursor. |
|
Oh that's smart. Shouldn't be too difficult, will try tomorrow! As for improving the structure, did you have anything specific in mind for implementing traits and moving to router? |
Nothing specific, will let you know if I came up with something. |
|
@swanandx Pushed some new changes to my branch. Your idea for shared cursor worked great, haven't measured the performance increase but feels a loot better. Also restructured some code, not sure how you would like it to be but moved the shared subscriptions part to it's own impl block to keep it a bit cleaner. Also implemented |
|
closing this in favor of #668 🚀 |
This PR adds support for shared subscriptions in broker with sticky strategy ( i.e. keep sending to one client in group until failure ).
Other strategies like round-robin, sticky, hash aren't included yet, as they might need significant refactoring. ( please let me know if you have any workarounds for it! )
Type of change
New feature (non-breaking change which adds functionality)
Checklist:
cargo fmtCHANGELOG.mdif its relevant of user of the library. If its not relevant mention why. ( TODO )