--- Another migration question… With IO gone, how ...
# arrow
j
--- Another migration question… With IO gone, how can I replicate this IO retry functionality?
Copy code
fun <T> IO<T>.retry(
  until: (T) -> Boolean = { true },
  additionalTimes: Int = 4,
  initialDelay: Duration = 500.milliseconds
): IO<T> {
  val schedule = Schedule
    .withMonad(IO.monad()) {
      exponential<Either<Throwable, T>>(initialDelay)
        .untilInput<Either<Throwable, T>> { it.exists(until) }
        .and(recurs(additionalTimes))
        .jittered(IO.monadDefer())
        .zipRight(identity())
    }
  return map<Either<Throwable, T>> { it.right() }
    .handleError { it.left() }
    .repeat(IO.concurrent(dispatchers()), schedule).fix()
    .flatMap {
      it.fold({ throwable -> IO.raiseError(throwable) }, { t -> IO.just(t) })
    }
}
1
s
Rewritten to Arrow Fx Coroutines with
suspend
instead of
IO
this would look like this:
Copy code
@ExperimentalTime
suspend fun <T> retry(
  fa: suspend () -> T,
  until: (T) -> Boolean = { true },
  additionalTimes: Int = 4,
  initialDelay: Duration = 500.milliseconds
): T {
  val schedule =
    Schedule.exponential<Either<Throwable, T>>(initialDelay)
      .untilInput<Either<Throwable, T>> { it.exists(until) }
      .and(Schedule.recurs(additionalTimes))
      .jittered()
      .zipRight(Schedule.identity())

  return schedule.repeat {
    Either.catch { fa() }
  }.fold({ throwable -> throw throwable }, ::identity)
}
1
🙌 1
Arrow Fx and
IO
is deprecated in favor of Arrow Fx Coroutines and
suspend
but you can find all the same functionality such as
Schedule
there.
val arrowFxCoroutines = "io.arrow-kt:arrow-fx-coroutines:0.12.0"
j
Ah, thanks. I misread this initially.