-
Notifications
You must be signed in to change notification settings - Fork 443
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
consumer: FullJitterStrategy may increase backoff counter unexpectedly #195
Comments
Ideas on how to approach this:
I think I'd favor breaking the signature rather than a silent change in behavior. I'd also be surprised if many people are using custom backoff strategies. Thoughts? |
I see what you mean.
How would |
@mreiferson Something like this // Calculate returns a random duration of time [0, 2 ^ attempt) and a value
// indicating whether to increase the backoff counter.
func (s *FullJitterStrategy) Calculate(attempt int) (time.Duration, bool) {
// lazily initialize the RNG
s.rngOnce.Do(func() {
if s.rng != nil {
return
}
s.rng = rand.New(rand.NewSource(time.Now().UnixNano()))
})
backoffDuration := s.cfg.BackoffMultiplier *
time.Duration(math.Pow(2, float64(attempt)))
return time.Duration(s.rng.Intn(int(backoffDuration))),
backoffDuration <= s.cfg.MaxBackoffDuration
} |
Yea, that makes sense.
We simply don't know, although I tend to agree. The other "right" thing to do would be to bump the major version number. But given Go's pathetic dependency management situation, I don't think that's all that important. What do you think @jehiah? |
@mreiferson @jehiah I thought about the pros and cons of a Thoughts on these two approaches:
What do you think about changing the interface? Any other ideas? If changing the interface is the way to go, we could:
func (s *FullJitterStrategy) MaxBackoffLevel() int {
x := float64(s.cfg.MaxBackoffDuration / s.cfg.BackoffMultiplier)
return int(math.Ceil(math.Log2(x + 1)))
} |
I agree with your analysis. It's not great, and we should try to avoid it when possible, but I ultimately think that behavior of the library is more important than backwards compatibility and furthermore, given that compilation will break, end users will be notified before it can affect a production system. Let's modify the interface. When we go to stamp a stable release and write up migration docs, we can decide about version numbers. |
@mreiferson Thanks for taking the time to read through this. I'll raise a PR to change I noticed the code starts the backoff counter at 1, which means the lowest backoff will be It's been like this for a while but the tests are more recent. |
SGTM re: off-by-one 😜 |
go-nsq/consumer.go
Lines 781 to 786 in 3c0c5ed
If
FullJitterStrategy
calculates a value less thanconfig.MaxBackoffDuration
thenbackoffCounter
will increment whereExponentialStrategy
wouldn't, potentially causinginBackoff()
andRDY 1
to persist longer than intended.This probably matters very little for most use cases, but during a prolonged outage and long-running handlers it could take a while to recover.
The text was updated successfully, but these errors were encountered: