Skip to content

Commit

Permalink
Merge 10a3e4b into ab6b09b
Browse files Browse the repository at this point in the history
  • Loading branch information
kromanovs committed Jun 26, 2019
2 parents ab6b09b + 10a3e4b commit a37bec1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/main/scala/com/evolutiongaming/retry/Retry.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ object Retry {
zero = (Status.empty(now), strategy.decide)
result <- zero.tailRecM[F, A] { case (status, decide) =>
fa.redeemWith[Either[S, A], E](
error => retry[A](status, decide, error),
error => retry[A](status.raiseError(error), decide, error),
result => result.asRight[(Status, Decide)].pure[F])
}
} yield result
Expand Down Expand Up @@ -200,13 +200,32 @@ object Retry {

Strategy(recur(strategy.decide))
}

def giveUpOn(strategy: Strategy, errorFilter: Any => Boolean): Strategy = {

def recur(decide: Decide): Decide = new Decide {

def apply(status: Status, now: Instant) = {
val result = status.error.fold(decide(status, now)) { error =>
if (errorFilter(error)) StrategyDecision.giveUp else decide(status, now)
}
result.mapDecide(recur)
}
}

Strategy(recur(strategy.decide))
}
}


final case class Status(retries: Int, delay: FiniteDuration, last: Instant) { self =>
final case class Status(retries: Int, delay: FiniteDuration, last: Instant, error: Option[Any] = none) { self =>

def plus(delay: FiniteDuration): Status = {
copy(retries = retries + 1, delay = self.delay + delay)
copy(retries = retries + 1, delay = self.delay + delay, error = none)
}

def raiseError[E](e: E): Status = {
copy(error = e.some)
}
}

Expand Down Expand Up @@ -279,6 +298,8 @@ object Retry {
def limit(max: FiniteDuration): Strategy = Strategy.limit(self, max)

def resetAfter(cooldown: FiniteDuration): Strategy = Strategy.resetAfter(self, cooldown)

def giveUpOn(errorFilter: Any => Boolean): Strategy = Strategy.giveUpOn(self, errorFilter)
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/test/scala/com/evolutiongaming/retry/RetrySpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,25 @@ class RetrySpec extends FunSuite with Matchers {
5.millis))
actual shouldEqual expected
}

test("giveUpOn") {
val strategy = Strategy.const(1.millis).giveUpOn {
case _: Error => true
case _ => false
}
val call = StateT { _.call }
val result = Retry(strategy, onError).apply(call)

val initial = State(toRetry = 2)
val actual = result.run(initial).map(_._1)
val expected = State(
toRetry = 1,
decisions = List(Details(decision = Decision.giveUp, retries = 0)),
delays = Nil
)
actual shouldEqual expected
}

}

object RetrySpec {
Expand Down

0 comments on commit a37bec1

Please sign in to comment.