Skip to content

Commit 942a576

Browse files
author
Roman Janusz
committed
fixed overflow in exponential backoff RetryStrategy
1 parent 9ecda72 commit 942a576

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

commons-core/src/main/scala/com/avsystem/commons/concurrent/RetryStrategy.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.avsystem.commons
22
package concurrent
33

4-
import scala.concurrent.duration.{Duration, FiniteDuration}
4+
import scala.concurrent.duration._
55

66
/**
77
* A `RetryStrategy` is conceptually a lazy sequence of delays, possibly infinite.
@@ -84,10 +84,10 @@ object RetryStrategy {
8484
apply(Opt((delay, continually(delay))))
8585

8686
def exponentially(firstDelay: FiniteDuration, factor: Double = 2): RetryStrategy = apply {
87-
val nextStrat = firstDelay * factor match {
88-
case fd: FiniteDuration => exponentially(fd, factor)
89-
case _ => never
90-
}
87+
val nextNanos = firstDelay.toNanos * factor
88+
val nextStrat =
89+
if (nextNanos > Long.MaxValue) continually(Long.MaxValue.nanos)
90+
else exponentially(nextNanos.nanos, factor)
9191
Opt((firstDelay, nextStrat))
9292
}
9393
}

commons-core/src/test/scala/com/avsystem/commons/concurrent/ExponentialBackoffTest.scala

+9-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ import scala.concurrent.duration._
1313
class ExponentialBackoffTest extends AnyFunSuite with Matchers {
1414
test("simple") {
1515
import RetryStrategy._
16-
val eb = immediately.andThen(exponentially(1.second)).maxDelay(20.seconds).maxRetries(8)
16+
val eb = immediately.andThen(exponentially(1.second)).maxDelay(20.seconds).maxRetries(64)
1717

1818
val allDelays = Iterator.iterateUntilEmpty(eb.nextRetry)(_._2.nextRetry).map(_._1).toList
1919
allDelays shouldBe List(
20-
Duration.Zero, 1.second, 2.seconds, 4.seconds, 8.seconds, 16.seconds, 20.seconds, 20.seconds
20+
Duration.Zero, 1.second, 2.seconds, 4.seconds, 8.seconds, 16.seconds, 20.seconds, 20.seconds,
21+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
22+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
23+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
24+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
25+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
26+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
27+
20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds, 20.seconds,
2128
)
2229
}
2330
}

0 commit comments

Comments
 (0)