From 7ba40b238ab6a400269349ffe022ae080c5c28a8 Mon Sep 17 00:00:00 2001 From: pwliwanow Date: Mon, 29 Jan 2018 12:05:28 +0100 Subject: [PATCH] Fix in BackoffSupervisor.calculateDelay #24419 --- .../akka/pattern/BackoffSupervisorSpec.scala | 28 +++++++++++++++++-- .../akka/pattern/BackoffSupervisor.scala | 16 +++++------ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/akka-actor-tests/src/test/scala/akka/pattern/BackoffSupervisorSpec.scala b/akka-actor-tests/src/test/scala/akka/pattern/BackoffSupervisorSpec.scala index cc6aab7a95..05f9570494 100644 --- a/akka-actor-tests/src/test/scala/akka/pattern/BackoffSupervisorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/pattern/BackoffSupervisorSpec.scala @@ -4,11 +4,12 @@ package akka.pattern -import scala.concurrent.duration._ import akka.actor._ import akka.testkit._ +import org.scalatest.prop.TableDrivenPropertyChecks._ + +import scala.concurrent.duration._ import scala.util.control.NoStackTrace -import akka.actor.SupervisorStrategy object BackoffSupervisorSpec { @@ -218,5 +219,28 @@ class BackoffSupervisorSpec extends AkkaSpec with ImplicitSender { expectNoMsg(500.milliseconds) } } + + "correctly calculate the delay" in { + val delayTable = + Table( + ("restartCount", "minBackoff", "maxBackoff", "randomFactor", "expectedResult"), + (0, 0.minutes, 0.minutes, 0d, 0.minutes), + (0, 5.minutes, 7.minutes, 0d, 5.minutes), + (2, 5.seconds, 7.seconds, 0d, 7.seconds), + (2, 5.seconds, 7.days, 0d, 20.seconds), + (29, 5.minutes, 10.minutes, 0d, 10.minutes), + (29, 10000.days, 10000.days, 0d, 10000.days), + (Int.MaxValue, 10000.days, 10000.days, 0d, 10000.days)) + forAll(delayTable) { ( + restartCount: Int, + minBackoff: FiniteDuration, + maxBackoff: FiniteDuration, + randomFactor: Double, + expectedResult: FiniteDuration) ⇒ + + val calculatedValue = BackoffSupervisor.calculateDelay(restartCount, minBackoff, maxBackoff, randomFactor) + assert(calculatedValue === expectedResult) + } + } } } diff --git a/akka-actor/src/main/scala/akka/pattern/BackoffSupervisor.scala b/akka-actor/src/main/scala/akka/pattern/BackoffSupervisor.scala index a173ac08fd..75e1e4470b 100644 --- a/akka-actor/src/main/scala/akka/pattern/BackoffSupervisor.scala +++ b/akka-actor/src/main/scala/akka/pattern/BackoffSupervisor.scala @@ -3,7 +3,6 @@ */ package akka.pattern -import scala.concurrent.duration.{ Duration, FiniteDuration } import java.util.concurrent.ThreadLocalRandom import java.util.Optional @@ -17,6 +16,9 @@ import akka.actor.SupervisorStrategy.Escalate import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy +import scala.concurrent.duration.{ Duration, FiniteDuration } +import scala.util.Try + object BackoffSupervisor { /** @@ -152,13 +154,11 @@ object BackoffSupervisor { maxBackoff: FiniteDuration, randomFactor: Double): FiniteDuration = { val rnd = 1.0 + ThreadLocalRandom.current().nextDouble() * randomFactor - if (restartCount >= 30) // Duration overflow protection (> 100 years) - maxBackoff - else - maxBackoff.min(minBackoff * math.pow(2, restartCount)) * rnd match { - case f: FiniteDuration ⇒ f - case _ ⇒ maxBackoff - } + val calculatedDuration = Try(maxBackoff.min(minBackoff * math.pow(2, restartCount)) * rnd).getOrElse(maxBackoff) + calculatedDuration match { + case f: FiniteDuration ⇒ f + case _ ⇒ maxBackoff + } } }