-
Notifications
You must be signed in to change notification settings - Fork 46
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
Create version for exponential backoff with max capped delay #187
Comments
I'm not sure what you mean by "logical delay". Do you have a link to the Akka docs for this feature? Or some sample code to show what it looks like in Akka? |
In akka we have this functionality: RestartSource.onFailuresWithBackoff(
minBackoff = 3.seconds,
maxBackoff = 30.seconds,
randomFactor = 0.2,
maxRestarts = -1
)(() => YourStream) When we migrate to fs2 i wrote this policy for reproduce this behavior in cats-retry: def exponentialRandomBackoff[M[_] : Applicative](
minBackoff: FiniteDuration,
maxBackoff: FiniteDuration,
randomFactor: Double,
maxRestarts: Int
): RetryPolicy[M] =
RetryPolicy.liftWithShow[M]({
status =>
if (maxRestarts == -1 || status.retriesSoFar < maxRestarts) {
val delay =
if (status.previousDelay.exists(_ >= maxBackoff))
maxBackoff
else {
//Copy-paste from RetryPolicies.safeMultiply
val durationNanos = BigInt(minBackoff.toNanos)
val resultNanos = durationNanos * BigInt(Math.pow(2, status.retriesSoFar.toDouble).toLong)
val safeResultNanos = resultNanos min BigInt(Long.MaxValue)
val duration_ = (FiniteDuration(safeResultNanos.toLong, TimeUnit.NANOSECONDS) *
(1.0 + Random.nextDouble() * randomFactor)) min maxBackoff
FiniteDuration(duration_.toNanos, TimeUnit.NANOSECONDS)
}
DelayAndRetry(delay)
} else
GiveUp
}, show"exponentialRandomBackoff(minBackoff=$minBackoff, maxBackoff=$maxBackoff, randomFactor=$randomFactor, maxRestarts=$maxRestarts)") Also i reference path of this code issue in #188 |
I rewrite this example with built-in functions: def exponentialRandomBackoff[M[_] : Applicative](
minBackoff: FiniteDuration,
maxBackoff: FiniteDuration,
randomFactor: Double,
maxRestarts: Int
): RetryPolicy[M] =
RetryPolicy
.withShow[M](
{ status =>
RetryPolicies.exponentialBackoff[M](minBackoff).decideNextRetry(status).map {
case GiveUp => GiveUp
case DelayAndRetry(delay) =>
val nextDelay = delay * (1.0 + Random.nextDouble() * randomFactor)
DelayAndRetry(FiniteDuration(nextDelay.toNanos, TimeUnit.NANOSECONDS))
}
},
show"exponentialRandomBackoff(minBackoff=$minBackoff, randomFactor=$randomFactor)"
)
.meet(RetryPolicies.constantDelay(maxBackoff))
.join(
if (maxRestarts == -1)
RetryPolicies.constantDelay[M](Duration.Zero)
else
RetryPolicies.limitRetries[M](maxRestarts)
) So i think that we can put something like this in lib would be helpful for devs who migrate from akka-streams to fs2. |
Similar to akka i wanna have ability to create exponential backoff retry policy with max capped delay just for keep logical delay, not like 10 minutes.
I can create PR by myself if you don't mind :)
The text was updated successfully, but these errors were encountered: