Johan Basson
09/01/2020, 9:43 AMtypealias GetCustomer = (config: Config, domain: Domain) -> IO<Either<ApiError, Option<CustomerDetails>>>
which will do a rest call to get CustomerDetails
Reading the arrow documentation i managed to get this:
val io = getCustomer(cloudConfig, domain).repeat(IO.concurrent(), Schedule.doWhile(IO.monad()) { it.isEmpty()})
val maybeCustomer = EitherT(io).bind()
How can i add exponential backoff with a max retries of 10 starting with a 1 second delay?Jannis
09/01/2020, 11:00 AMSchedule.withMonad(IO.monad()) {
exponential(1.seconds).whileInput { it.isEmpty() } and recurs(10)
}
This should give you a policy that uses exponential backoff starting with 1 second as long as the input (the result of whatever we are repeating/retrying) holds the predicate. Then we combine with and to force it to stop after 10 retries.
and
combines two schedules and only repeats/retries if both of them would and picks the longer delay of the two (recurs has no delay so it picks exponentials delay)
You might also want to consider calling jittered
to avoid a coordinated retry when the service fails (If there is not a huge amount of traffic this likely won't matter, if there is use jittered
to slightly randomize the delay of each retry. The bounds are configurable^^)Jannis
09/01/2020, 11:03 AMzipRight(identity())
to get the result of the computation^^Jannis
09/01/2020, 11:06 AMSchedule.withMonad(IO.monad()) {
(exponential(1.seconds).whileInput { it.isEmpty() } and recurs(10))
.jittered(IO.monadDefer())
.zipRight(identity())
}
Johan Basson
09/01/2020, 1:00 PM