-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
client: re-define the meaning of poke() #41
Conversation
4e3b196
to
20e0fa8
Compare
✅ Build pvxs 1.0.876 completed (commit 38c680ded5 by @mdavidsaver) |
@thomasives If you have time, I'd be interested to have your thoughts on this idea. |
This looks like a good change to me. I think this will ensure there aren't any more pathological cases where we end up flooding the network with UDP packets.
I don't understand this comment, I don't think you are changing how is done Just a thought that isn't directly about this PRI think there is a small issue that remains even with this PR. In order to avoid UDP bursts, I think we should be aiming for a uniform distribution of channels between all the buckets. I doubt we will get a uniform distribution for a typical application currently. I suspect that a typical application will be creating channels in bursts which will result in them all being placed in the same bucket. With how the channels are being rescheduled now, I think that they will end up being rescheduled to the same bucket, assuming they aren't found (e.g. the IOC is offline). So, in typical situations I think we would expect channels to remain clumped in the search ring. (It would be interesting to try and measure this to see if this analysis is correct.) This obviously will result in the bursts of UDP activity which we want to avoid. I assume something similar will happen when an IOC disappears, all the channels from that IOC will presumably end up in the same bucket (I haven't checked the code for this though) and will thus remain clumped. I think you have mentioned something about placing channels in the initial bucket randomly. This would fix the issue of clumping, although it would be a shame for an unlucky channel to wait up to 30 seconds before it is included in a search request for the second time. Perhaps you could randomise its placement to between the first 3-4 buckets and then randomise |
@@ -1074,7 +1094,7 @@ void ContextImpl::tickSearch(SearchKind kind) | |||
count++; | |||
|
|||
size_t ninc = 0u; | |||
if(kind==SearchKind::check) | |||
if(kind==SearchKind::check && !poked) | |||
ninc = chan->nSearch = std::min(searchBuckets.size(), chan->nSearch+1u); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this comment, I don't think you are changing how is done initialSearchS is working, so I don't see how this would affect recently created channels negatively.
I'm referring to this line, where nSearch
won't be incremented during a "fast" cycle. In this context, "recently created" means a channel which has already passed through the special initial search buckect, but where nSearch < nBuckets
.
I do have some code which attempts to "level" adjacent buckets in the long run. This logic is largely a guess on my part. I don't have any measurements to justify it. I'm using the number of channels in a bucket because I don't have a ready way to track this as number of UDP packets. (thus the magic number |
As a follow on to #39. This PR changes the meaning of
poke()
and the user facinghurryUp()
method.Actions which can
poke()
the client search process.Context::hurryUp()
Currently, the action of
poke()
is to immediately expiresearchTimer
, sending search packets for any disconnected channels in the next bucket. There is a 30 second "hold-off" timer to keep this from happening too often, but this is only applied to beacon events.This PR applies the hold-off timer to all causes, and changes the effect. A successful
poke()
will now switchsearchTimer
to a shorter interval (1 second -> 0.2 second) fornBuckets
periods, and omit incrementing the search delay (Channel::nSearch
). Effectively, this gives a 5x speed up of the search process for one revolution of the search bucket wheel (6 seconds) before returning to the normal period for the remaining 24 seconds of the hold-off period. Though it will be an effective slow down for very recently created channels.My thinking is that this will allow for (hopefully) occasional speedups of the search process, allowing for reduction of (re)connect latency. However, his will increase both the possible peak and average UDP traffic levels if eg. beacons from a flapping server frequently trigger new server detection. I think that this will be bounded to less than twice the normal levels on average as 24 of 30 buckets would be searched twice within one hold-off period, and the remaining 6 once.