Skip to content
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

Incorrect retry backoff delay calculation #315

Open
PetrGlad opened this issue Nov 16, 2017 · 2 comments
Open

Incorrect retry backoff delay calculation #315

PetrGlad opened this issue Nov 16, 2017 · 2 comments

Comments

@PetrGlad
Copy link
Contributor

See class ExponentialRety, here.

In case this.unit is not milliseconds, this line will produce unexpected series of delay values. For example, leaving aside workingAttempts suared:

// this.unit == TImeUnit.SECONDS
x = TimeUnit.toSeconds(1) // Let's assume we have got this from builder
x = TimeUnit.toMillis(1) // First iteration
// x == 1000
x = TimeUnit.toMillis(1) // Second iteration
// x == 1000000
// and so on..

So in case unit is not millis then this conversion alone would add at least +/-3 orders of magnitude coefficient. I believe this was not the intention.

I think reasonable approach here would be to move all unit conversions to builder and then default to milliseconds internally.

Possibly related question is regarding this condition workingInterval <= 0. It may become true in case workingInterval <= 0 or workingAttempts == 0. The latter does not hold as it is initially 1 and always increased. workingInterval can be 0 or less only if we have percentOfMaxIntervalForJitter >= 100 which is not checked by builder...
Maybe use one of approaches suggested here instead? They are relatively easier to reason about.

@dehora
Copy link
Owner

dehora commented Nov 25, 2017

@PetrGlad Thanks for the report - failing test cases would be useful.

@PetrGlad
Copy link
Contributor Author

PetrGlad commented Nov 27, 2017

OK, it turns out that I cannot trigger this without modifying the ExponentialRetry code. ExponentialRetry.Builder#unit is declared as final with value TimeUnit.SECONDS and this is only value for which workingInterval = unit.toMillis(workingInterval) * (workingAttempts * workingAttempts); would work correctly and this is only time unit for which toMillis is identity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants