From 00a9746a4cac55829fbf7b1d979873149b74c941 Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Wed, 15 May 2019 11:25:56 +0200 Subject: [PATCH 1/9] Initial impl --- .../arrow/effects/internal/ConcurrentSleep.kt | 51 +++++++++++++++++++ .../arrow/effects/typeclasses/Concurrent.kt | 23 +++++++++ 2 files changed, 74 insertions(+) create mode 100644 modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt new file mode 100644 index 00000000000..6defe01849e --- /dev/null +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -0,0 +1,51 @@ +package arrow.effects.internal + +import arrow.Kind +import arrow.core.Either +import arrow.core.Left +import arrow.core.Right +import arrow.effects.typeclasses.Concurrent +import arrow.effects.typeclasses.Duration +import arrow.effects.typeclasses.mapUnit +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import kotlin.coroutines.Continuation +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.startCoroutine + + +fun Concurrent.ConcurrentSleep(duration: Duration): Kind = cancelable { cb -> + val cancelRef = scheduler.schedule(ShiftTick(dispatchers().default(), cb), duration.amount, duration.timeUnit) + delay { cancelRef.cancel(false).let(mapUnit) } +} + +/** + * [scheduler] is **only** for internal use for the [Concurrent.sleep] implementation. + * This way we can guarantee nothing besides sleeping ever occurs here. + */ +internal val scheduler: ScheduledExecutorService by lazy { + Executors.newScheduledThreadPool(2) { r -> + Thread(r).apply { + name = "arrow-effect-scheduler-$id" + isDaemon = true + } + } +} + +/** + * [ShiftTick] is a small utility to [Concurrent.shift] work away from the [ScheduledExecutorService]. + * As mentioned in [scheduler] no work should ever happen there. + * So after sleeping we need to shift away to not keep that thread occupied. + */ +internal class ShiftTick( + private val ctx: CoroutineContext, + private val cb: (Either) -> Unit +) : Runnable { + override fun run() { + suspend { Unit }.startCoroutine(Continuation(ctx) { + it.fold({ unit -> cb(Right(unit)) }, { e -> cb(Left(e)) }) + }) + } +} + +class TimeoutException(message: String) : Exception(message) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt index 800f9c5abad..220e44953ec 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt @@ -13,6 +13,10 @@ import arrow.effects.CancelToken import arrow.effects.KindConnection import arrow.effects.MVar import arrow.effects.data.internal.BindingCancellationException +import arrow.effects.internal.ConcurrentSleep +import arrow.effects.internal.ShiftTick +import arrow.effects.internal.TimeoutException +import arrow.effects.internal.scheduler import arrow.typeclasses.MonadContinuation import java.util.concurrent.atomic.AtomicReference import kotlin.coroutines.CoroutineContext @@ -722,6 +726,25 @@ interface Concurrent : Async { override fun binding(c: suspend MonadContinuation.() -> B): Kind = bindingCancellable { c() }.a + + fun sleep(duration: Duration): Kind = + ConcurrentSleep(duration) + + fun Kind.timeoutTo(default: Kind, duration: Duration): Kind = + dispatchers().default().raceN(this, sleep(duration)).flatMap { + it.fold( + { a -> just(a) }, + { default } + ) + } + + fun Kind.timeout(duration: Duration): Kind = + dispatchers().default().raceN(this, sleep(duration)).flatMap { + it.fold( + { a -> just(a) }, + { raiseError(TimeoutException(duration.toString())) } + ) + } } /** Alias for `Either` structure to provide consistent signature for race methods. */ From b1e0f3963dd07532d938f8d5b5b420921ed3f1b9 Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Wed, 15 May 2019 15:52:22 +0200 Subject: [PATCH 2/9] Add docs --- .../src/main/kotlin/SyntaxHelper.kt | 6 ++ .../arrow/effects/internal/ConcurrentSleep.kt | 2 +- .../arrow/effects/typeclasses/Concurrent.kt | 68 +++++++++++++++++-- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt b/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt index a971375cf1f..f4f78c44a8d 100644 --- a/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt +++ b/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt @@ -3,6 +3,8 @@ package com.example.domain import arrow.data.ListK import arrow.data.MapK import arrow.optics.optics +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking @optics data class Street(val number: Int, val name: String) { @@ -56,3 +58,7 @@ data class HttpError(val message: String) : NetworkError() { } object TimeoutError : NetworkError() + +fun main() = runBlocking { + delay(1000) +} diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt index 6defe01849e..5d98fdd93ed 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -13,7 +13,7 @@ import kotlin.coroutines.Continuation import kotlin.coroutines.CoroutineContext import kotlin.coroutines.startCoroutine - +@Suppress("FunctionName") fun Concurrent.ConcurrentSleep(duration: Duration): Kind = cancelable { cb -> val cancelRef = scheduler.schedule(ShiftTick(dispatchers().default(), cb), duration.amount, duration.timeUnit) delay { cancelRef.cancel(false).let(mapUnit) } diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt index 220e44953ec..678a8ef7013 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt @@ -14,9 +14,7 @@ import arrow.effects.KindConnection import arrow.effects.MVar import arrow.effects.data.internal.BindingCancellationException import arrow.effects.internal.ConcurrentSleep -import arrow.effects.internal.ShiftTick import arrow.effects.internal.TimeoutException -import arrow.effects.internal.scheduler import arrow.typeclasses.MonadContinuation import java.util.concurrent.atomic.AtomicReference import kotlin.coroutines.CoroutineContext @@ -727,9 +725,50 @@ interface Concurrent : Async { override fun binding(c: suspend MonadContinuation.() -> B): Kind = bindingCancellable { c() }.a - fun sleep(duration: Duration): Kind = - ConcurrentSleep(duration) + /** + * Sleeps for a given [duration] without blocking a thread. + * Used to derive combinators [timeout], [timeoutTo] and can be used to created timed events. + * + * ```kotlin:ank:playground + * import arrow.effects.* + * import arrow.effects.extensions.io.concurrent.concurrent + * + * fun main(args: Array) { + * //sampleStart + * fun Concurrent.delayHelloWorld(): Kind = + * sleep(3.seconds).flatMap { + * delay { println("Hello World!") } + * } + * //sampleEnd + * IO.unsafeRunBlocking(IO.concurrent().delayHelloWorld()) + * } + * ``` + * @see timeout + * @see timeoutTo + **/ + fun sleep(duration: Duration): Kind = ConcurrentSleep(duration) + /** + * Returns the result of [this] within the specified [duration] or the [default] value. + * + * ```kotlin:ank:playground + * import arrow.effects.* + * import arrow.effects.extensions.io.concurrent.concurrent + * import arrow.effects.typeclasses.seconds + * + * fun main(args: Array) { + * //sampleStart + * fun Concurrent.timedOutWorld(): Kind { + * val world = sleep(3.seconds).flatMap { delay { println("Hello World!") } } + * val fallbackWorld = delay { println("Hello from the backup") } + * return world.timeoutTo(fallbackWorld, 1.seconds) + * } + * //sampleEnd + * IO.unsafeRunBlocking(IO.concurrent().timedOutWorld()) + * } + * ``` + * @see timeout + **/ fun Kind.timeoutTo(default: Kind, duration: Duration): Kind = dispatchers().default().raceN(this, sleep(duration)).flatMap { it.fold( @@ -738,6 +777,27 @@ interface Concurrent : Async { ) } + /** + * Returns the result of [this] within the specified [duration] or raises a [TimeoutException]. + * + * ```kotlin:ank:playground + * import arrow.effects.* + * import arrow.effects.extensions.io.concurrent.concurrent + * import arrow.effects.typeclasses.seconds + * + * fun main(args: Array) { + * //sampleStart + * fun Concurrent.timedOutWorld(): Kind { + * val world = sleep(3.seconds).flatMap { delay { println("Hello World!") } } + * return world.timeout(1.seconds) + * } + * //sampleEnd + * IO.unsafeRunBlocking(IO.concurrent().timedOutWorld()) + * } + * ``` + * @see timeout + * @see timeoutTo + **/ fun Kind.timeout(duration: Duration): Kind = dispatchers().default().raceN(this, sleep(duration)).flatMap { it.fold( From f5c5e3b572ad876a92633b64ef71b2196a4b1fb8 Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Sun, 19 May 2019 18:30:41 +0200 Subject: [PATCH 3/9] Clean-up PR --- modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt | 6 ------ .../main/kotlin/arrow/effects/internal/ConcurrentSleep.kt | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt b/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt index f4f78c44a8d..a971375cf1f 100644 --- a/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt +++ b/modules/docs/arrow-docs/src/main/kotlin/SyntaxHelper.kt @@ -3,8 +3,6 @@ package com.example.domain import arrow.data.ListK import arrow.data.MapK import arrow.optics.optics -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking @optics data class Street(val number: Int, val name: String) { @@ -58,7 +56,3 @@ data class HttpError(val message: String) : NetworkError() { } object TimeoutError : NetworkError() - -fun main() = runBlocking { - delay(1000) -} diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt index 5d98fdd93ed..b0dda9da1cf 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -16,7 +16,7 @@ import kotlin.coroutines.startCoroutine @Suppress("FunctionName") fun Concurrent.ConcurrentSleep(duration: Duration): Kind = cancelable { cb -> val cancelRef = scheduler.schedule(ShiftTick(dispatchers().default(), cb), duration.amount, duration.timeUnit) - delay { cancelRef.cancel(false).let(mapUnit) } + delay { cancelRef.cancel(false); Unit } } /** From c64e21ceb68214f3e7d937597f234f3dcc9e621e Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Sun, 19 May 2019 18:59:44 +0200 Subject: [PATCH 4/9] ktlintFormat --- .../src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt index b0dda9da1cf..7f103ee98e4 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -6,7 +6,6 @@ import arrow.core.Left import arrow.core.Right import arrow.effects.typeclasses.Concurrent import arrow.effects.typeclasses.Duration -import arrow.effects.typeclasses.mapUnit import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import kotlin.coroutines.Continuation From 117c1f275150a127f9816a86160844957872862d Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Sun, 19 May 2019 19:35:42 +0200 Subject: [PATCH 5/9] Add missing access modifier --- .../src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt index 7f103ee98e4..6583f7e2586 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -13,7 +13,7 @@ import kotlin.coroutines.CoroutineContext import kotlin.coroutines.startCoroutine @Suppress("FunctionName") -fun Concurrent.ConcurrentSleep(duration: Duration): Kind = cancelable { cb -> +internal fun Concurrent.ConcurrentSleep(duration: Duration): Kind = cancelable { cb -> val cancelRef = scheduler.schedule(ShiftTick(dispatchers().default(), cb), duration.amount, duration.timeUnit) delay { cancelRef.cancel(false); Unit } } From fd7f108160fa6311fe747579936869697e4f98ba Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Mon, 20 May 2019 22:48:54 +0200 Subject: [PATCH 6/9] Update API --- .../arrow/effects/internal/ConcurrentSleep.kt | 4 +- .../arrow/effects/typeclasses/Concurrent.kt | 44 +++---------------- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt index 6583f7e2586..626ce2ecc32 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -47,4 +47,6 @@ internal class ShiftTick( } } -class TimeoutException(message: String) : Exception(message) +object TimeoutException : Exception() { + override fun fillInStackTrace(): Throwable = this +} diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt index 5dbac1365a4..917e59f7632 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt @@ -727,10 +727,11 @@ interface Concurrent : Async { /** * Sleeps for a given [duration] without blocking a thread. - * Used to derive combinators [timeout], [timeoutTo] and can be used to created timed events. + * Used to derive [waitFor] and can be used to created timed events like backing-off retries. * * ```kotlin:ank:playground * import arrow.effects.* + * import arrow.effects.typeclasses.* * import arrow.effects.extensions.io.concurrent.concurrent * * fun main(args: Array) { @@ -740,11 +741,10 @@ interface Concurrent : Async { * delay { println("Hello World!") } * } * //sampleEnd - * IO.unsafeRunBlocking(IO.concurrent().delayHelloWorld()) + * IO.concurrent().delayHelloWorld().unsafeRunSync() * } * ``` - * @see timeout - * @see timeoutTo + * @see waitFor **/ fun sleep(duration: Duration): Kind = ConcurrentSleep(duration) @@ -753,8 +753,8 @@ interface Concurrent : Async { * * ```kotlin:ank:playground * import arrow.effects.* + * import arrow.effects.typeclasses.* * import arrow.effects.extensions.io.concurrent.concurrent - * import arrow.effects.typeclasses.seconds * * fun main(args: Array) { * //sampleStart @@ -764,47 +764,17 @@ interface Concurrent : Async { * return world.timeoutTo(fallbackWorld, 1.seconds) * } * //sampleEnd - * IO.unsafeRunBlocking(IO.concurrent().timedOutWorld()) + * IO.concurrent().timedOutWorld().unsafeRunSync() * } * ``` - * @see timeout **/ - fun Kind.timeoutTo(default: Kind, duration: Duration): Kind = + fun Kind.waitFor(duration: Duration, default: Kind = raiseError(TimeoutException)): Kind = dispatchers().default().raceN(this, sleep(duration)).flatMap { it.fold( { a -> just(a) }, { default } ) } - - /** - * Returns the result of [this] within the specified [duration] or raises a [TimeoutException]. - * - * ```kotlin:ank:playground - * import arrow.effects.* - * import arrow.effects.extensions.io.concurrent.concurrent - * import arrow.effects.typeclasses.seconds - * - * fun main(args: Array) { - * //sampleStart - * fun Concurrent.timedOutWorld(): Kind { - * val world = sleep(3.seconds).flatMap { delay { println("Hello World!") } } - * return world.timeout(1.seconds) - * } - * //sampleEnd - * IO.unsafeRunBlocking(IO.concurrent().timedOutWorld()) - * } - * ``` - * @see timeout - * @see timeoutTo - **/ - fun Kind.timeout(duration: Duration): Kind = - dispatchers().default().raceN(this, sleep(duration)).flatMap { - it.fold( - { a -> just(a) }, - { raiseError(TimeoutException(duration.toString())) } - ) - } } /** Alias for `Either` structure to provide consistent signature for race methods. */ From ef30ba6b05b8c7a0a03497be76e2a86cacfb371e Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Tue, 21 May 2019 13:26:01 +0200 Subject: [PATCH 7/9] Fix docs --- .../arrow/effects/internal/ConcurrentSleep.kt | 4 +- .../arrow/effects/typeclasses/Concurrent.kt | 39 +++++++++++++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt index 626ce2ecc32..e640d957770 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/internal/ConcurrentSleep.kt @@ -47,6 +47,4 @@ internal class ShiftTick( } } -object TimeoutException : Exception() { - override fun fillInStackTrace(): Throwable = this -} +class TimeoutException(override val message: String) : Exception() diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt index 917e59f7632..5fc55552400 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt @@ -730,6 +730,7 @@ interface Concurrent : Async { * Used to derive [waitFor] and can be used to created timed events like backing-off retries. * * ```kotlin:ank:playground + * import arrow.* * import arrow.effects.* * import arrow.effects.typeclasses.* * import arrow.effects.extensions.io.concurrent.concurrent @@ -741,7 +742,8 @@ interface Concurrent : Async { * delay { println("Hello World!") } * } * //sampleEnd - * IO.concurrent().delayHelloWorld().unsafeRunSync() + * IO.concurrent().delayHelloWorld() + * .fix().unsafeRunSync() * } * ``` * @see waitFor @@ -752,6 +754,7 @@ interface Concurrent : Async { * Returns the result of [this] within the specified [duration] or the [default] value. * * ```kotlin:ank:playground + * import arrow.* * import arrow.effects.* * import arrow.effects.typeclasses.* * import arrow.effects.extensions.io.concurrent.concurrent @@ -764,17 +767,47 @@ interface Concurrent : Async { * return world.timeoutTo(fallbackWorld, 1.seconds) * } * //sampleEnd - * IO.concurrent().timedOutWorld().unsafeRunSync() + * IO.concurrent().timedOutWorld() + * .fix().unsafeRunSync() * } * ``` **/ - fun Kind.waitFor(duration: Duration, default: Kind = raiseError(TimeoutException)): Kind = + fun Kind.waitFor(duration: Duration, default: Kind): Kind = dispatchers().default().raceN(this, sleep(duration)).flatMap { it.fold( { a -> just(a) }, { default } ) } + + /** + * Returns the result of [this] within the specified [duration] or the raises a [TimeoutException] exception. + * + * ```kotlin:ank:playground + * import arrow.* + * import arrow.effects.* + * import arrow.effects.typeclasses.* + * import arrow.effects.extensions.io.concurrent.concurrent + * + * fun main(args: Array) { + * //sampleStart + * fun Concurrent.timedOutWorld(): Kind { + * val world = sleep(1.seconds).flatMap { delay { println("Hello World!") } } + * return world.waitFor(3.seconds) + * } + * //sampleEnd + * IO.concurrent().timedOutWorld() + * .fix().unsafeRunSync() + * } + * ``` + **/ + fun Kind.waitFor(duration: Duration): Kind = + dispatchers().default().raceN(this, sleep(duration)).flatMap { + it.fold( + { a -> just(a) }, + { raiseError(TimeoutException(duration.toString())) } + ) + } } /** Alias for `Either` structure to provide consistent signature for race methods. */ From aff3affdc4c6bed330707b208d388f5fef7501b1 Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Tue, 21 May 2019 14:46:18 +0200 Subject: [PATCH 8/9] Fix old API in docs --- .../src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt index 5fc55552400..5a7d0cf98a0 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt @@ -764,7 +764,7 @@ interface Concurrent : Async { * fun Concurrent.timedOutWorld(): Kind { * val world = sleep(3.seconds).flatMap { delay { println("Hello World!") } } * val fallbackWorld = delay { println("Hello from the backup") } - * return world.timeoutTo(fallbackWorld, 1.seconds) + * return world.waitFor(fallbackWorld, 1.seconds) * } * //sampleEnd * IO.concurrent().timedOutWorld() From 040a9741201c5eb05a14c188eeec9f3ec6c82f99 Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Tue, 21 May 2019 16:33:53 +0200 Subject: [PATCH 9/9] Fix docs --- .../src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt index 5a7d0cf98a0..3fb377fef26 100644 --- a/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt +++ b/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/typeclasses/Concurrent.kt @@ -764,7 +764,7 @@ interface Concurrent : Async { * fun Concurrent.timedOutWorld(): Kind { * val world = sleep(3.seconds).flatMap { delay { println("Hello World!") } } * val fallbackWorld = delay { println("Hello from the backup") } - * return world.waitFor(fallbackWorld, 1.seconds) + * return world.waitFor(1.seconds, fallbackWorld) * } * //sampleEnd * IO.concurrent().timedOutWorld()