Merge pull request #1924 from akka/wip-3690-CircuitBreakerOpenException-patriknw

=act #3690 Correct calculation of remainingDuration in CircuitBreakerOpenException
This commit is contained in:
Patrik Nordwall 2014-01-15 07:05:38 -08:00
commit 8e4dfbbb3d
2 changed files with 13 additions and 9 deletions

View file

@ -33,8 +33,9 @@ object CircuitBreakerSpec {
def longCallTimeoutCb()(implicit system: ActorSystem, ec: ExecutionContext): Breaker =
new Breaker(new CircuitBreaker(system.scheduler, 1, 5 seconds, 500.millis.dilated))
val longResetTimeout = 5.seconds
def longResetTimeoutCb()(implicit system: ActorSystem, ec: ExecutionContext): Breaker =
new Breaker(new CircuitBreaker(system.scheduler, 1, 100.millis.dilated, 5 seconds))
new Breaker(new CircuitBreaker(system.scheduler, 1, 100.millis.dilated, longResetTimeout))
def multiFailureCb()(implicit system: ActorSystem, ec: ExecutionContext): Breaker =
new Breaker(new CircuitBreaker(system.scheduler, 5, 200.millis.dilated, 500.millis.dilated))
@ -62,7 +63,9 @@ class CircuitBreakerSpec extends AkkaSpec with BeforeAndAfter {
checkLatch(breaker.openLatch)
intercept[CircuitBreakerOpenException] { breaker().withSyncCircuitBreaker(sayHi) }
val e = intercept[CircuitBreakerOpenException] { breaker().withSyncCircuitBreaker(sayHi) }
e.remainingDuration should be > (Duration.Zero)
e.remainingDuration should be <= (CircuitBreakerSpec.longResetTimeout)
}
"transition to half-open on reset timeout" in {

View file

@ -441,16 +441,17 @@ class CircuitBreaker(scheduler: Scheduler, maxFailures: Int, callTimeout: Finite
* @return Future containing result of protected call
*/
override def invoke[T](body: Future[T]): Future[T] =
Promise.failed[T](new CircuitBreakerOpenException(remainingTimeout().timeLeft)).future
Promise.failed[T](new CircuitBreakerOpenException(remainingDuration())).future
/**
* Calculate remaining timeout to inform the caller in case a backoff algorithm is useful
* Calculate remaining duration until reset to inform the caller in case a backoff algorithm is useful
*
* @return [[scala.concurrent.duration.Deadline]] to when the breaker will attempt a reset by transitioning to half-open
* @return duration to when the breaker will attempt a reset by transitioning to half-open
*/
private def remainingTimeout(): Deadline = get match {
case 0L Deadline.now
case t (t.millis + resetTimeout).fromNow
private def remainingDuration(): FiniteDuration = {
val diff = System.nanoTime() - get
if (diff <= 0L) Duration.Zero
else diff.nanos
}
/**
@ -474,7 +475,7 @@ class CircuitBreaker(scheduler: Scheduler, maxFailures: Int, callTimeout: Finite
* @return
*/
override def _enter(): Unit = {
set(System.currentTimeMillis)
set(System.nanoTime())
scheduler.scheduleOnce(resetTimeout) {
attemptReset()
}