Skip to content
This repository has been archived by the owner on Feb 24, 2021. It is now read-only.

Commit

Permalink
Fix Schedule type in retry methods (#297)
Browse files Browse the repository at this point in the history
* Fix Schedule type in retry methods

* Add a few small tests for repeat/retry

Co-authored-by: Alberto Ballano <aballano@users.noreply.github.com>
  • Loading branch information
1Jajen1 and aballano committed Nov 12, 2020
1 parent 5c2a46a commit 86bf8f3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ suspend fun <A, B, C> repeatOrElseEither(
* Returns the result of the effect if if it was successful or re-raises the last error encountered when the schedule ends.
*/
suspend fun <A, B> retry(
schedule: Schedule<A, B>,
schedule: Schedule<Throwable, B>,
fa: suspend () -> A
): A = retryOrElse(schedule, fa) { e, _ -> throw e }

Expand All @@ -801,7 +801,7 @@ suspend fun <A, B> retry(
* Also offers a function to handle errors if they are encountered during retrial.
*/
suspend fun <A, B> retryOrElse(
schedule: Schedule<A, B>,
schedule: Schedule<Throwable, B>,
fa: suspend () -> A,
orElse: suspend (Throwable, B) -> A
): A = retryOrElseEither(schedule, fa, orElse).fold(::identity, ::identity)
Expand All @@ -812,7 +812,7 @@ suspend fun <A, B> retryOrElse(
*/
@Suppress("UNCHECKED_CAST")
suspend fun <A, B, C> retryOrElseEither(
schedule: Schedule<A, B>,
schedule: Schedule<Throwable, B>,
fa: suspend () -> A,
orElse: suspend (Throwable, B) -> C
): Either<C, A> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package arrow.fx.coroutines

import arrow.core.Either
import arrow.core.Eval
import io.kotest.assertions.fail
import io.kotest.matchers.shouldBe
import kotlin.math.pow

Expand Down Expand Up @@ -175,10 +176,21 @@ class ScheduleTest : ArrowFxSpec(spec = {
l shouldBe Either.Left(stop)
}

"repeat fails fast on errors" {
val ex = Throwable("Hello")
repeatOrElseEither(Schedule.recurs(0), { throw ex }) { exc, _ -> exc }
.fold({ it shouldBe ex }, { fail("The impossible happened") })
}

"repeat should run the schedule with the correct input" {
var i = 0
repeat(Schedule.recurs<Int>(10).zipRight(Schedule.collect())) { i++ } shouldBe (0..10).toList()
}

"retry is stack-safe" {
val count = Atomic(0)
val l = Either.catch {
val n: Nothing = retry(Schedule.recurs(20_000)) {
retry(Schedule.recurs(20_000)) {
count.updateAndGet { it + 1 }
throw exception
}
Expand All @@ -187,6 +199,18 @@ class ScheduleTest : ArrowFxSpec(spec = {
l shouldBe Either.Left(exception)
count.get() shouldBe 20_001
}

"retry succeeds if no exception is thrown" {
retry(Schedule.recurs(0)) { 1 } shouldBe 1
}

"retryOrElseEither runs the schedule with the correct input and runs the orElse handler if it does not retry" {
val ex = Throwable("Hello")
val res = retryOrElseEither<Int, Int, Throwable>(Schedule.recurs(0), {
throw ex
}) { e, _ -> e }
res.fold({ it shouldBe ex }, { fail("The impossible happened") })
}
})

private fun fibs(one: Long): Sequence<Long> = generateSequence(Pair(0L, one)) { (a, b) ->
Expand Down

0 comments on commit 86bf8f3

Please sign in to comment.