diff --git a/core/src/main/scala/ox/resilience/AdaptiveRetry.scala b/core/src/main/scala/ox/resilience/AdaptiveRetry.scala index 49944147..a05814f8 100644 --- a/core/src/main/scala/ox/resilience/AdaptiveRetry.scala +++ b/core/src/main/scala/ox/resilience/AdaptiveRetry.scala @@ -76,7 +76,7 @@ case class AdaptiveRetry( // If we want to retry we try to acquire tokens from bucket if config.resultPolicy.isWorthRetrying(value) then if shouldPayFailureCost(Left(value)) then ScheduleStop(!tokenBucket.tryAcquire(failureCost)) - else ScheduleStop.Yes + else ScheduleStop.No else ScheduleStop.Yes case Right(value) => // If we are successful, we release tokens to bucket and end schedule diff --git a/core/src/test/scala/ox/resilience/ImmediateRetryTest.scala b/core/src/test/scala/ox/resilience/ImmediateRetryTest.scala index cec1b425..37a7c5ad 100644 --- a/core/src/test/scala/ox/resilience/ImmediateRetryTest.scala +++ b/core/src/test/scala/ox/resilience/ImmediateRetryTest.scala @@ -210,4 +210,22 @@ class ImmediateRetryTest extends AnyFlatSpec with EitherValues with TryValues wi result.value shouldBe message counter shouldBe 6 + it should "not pay failureCost if result E is going to be retried and shouldPayFailureCost returns false" in: + // given + var counter = 0 + val errorMessage = "boom" + + def f = + counter += 1 + Left(errorMessage) + + val adaptive = AdaptiveRetry(TokenBucket(2), 1, 1) + // when + val result = adaptive.retryEither(Schedule.immediate.maxRetries(5), _ => false)(f) + + // then + result.left.value shouldBe errorMessage + // all attempts are made for free, without paying the failure cost: one initial + five retries + counter shouldBe 6 + end ImmediateRetryTest