Arrow Fx. Auto cancels without leaving to user discipline to check for `isAlive`. Examples by @nomisRev
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import arrow.fx.* | |
import arrow.fx.extensions.* | |
import arrow.fx.typeclasses.* | |
import arrow.fx.extensions.io.bracket.guaranteeCase | |
fun <A> IOOf<A>.onCancel(token: IOOf<Unit>): IO<A> = | |
guaranteeCase { case -> | |
when (case) { | |
ExitCase.Canceled -> token | |
else -> IO.unit | |
} | |
} | |
//sampleStart | |
fun sleeping(i: Int): IO<Unit> = | |
IO.effect { println("$i starts sleeping") } | |
.followedBy(IO.sleep(i.seconds)) | |
.onCancel(IO.effect { println("$i is getting cancelled and woken up!") }) | |
suspend fun main(): Unit = IO.fx { | |
val (_, cancel) = !listOf(sleeping(1), sleeping(2), sleeping(3)) | |
.parSequence() | |
.effectMap { println("Finished") } | |
.fork() | |
!sleep(1.seconds) | |
!cancel | |
}.suspended() | |
//sampleEnd | |
/** | |
2 starts sleeping | |
1 starts sleeping | |
3 starts sleeping | |
3 is getting cancelled and woken up! | |
2 is getting cancelled and woken up! | |
1 is getting cancelled and woken up! | |
**/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import arrow.fx.IO | |
import arrow.fx.IOOf | |
import arrow.fx.extensions.fx | |
import arrow.fx.extensions.io.bracket.guaranteeCase | |
import arrow.fx.typeclasses.ExitCase | |
import arrow.fx.typeclasses.seconds | |
fun <A> IOOf<A>.onCancel(token: IOOf<Unit>): IO<A> = | |
guaranteeCase { case -> | |
when (case) { | |
ExitCase.Canceled -> token | |
else -> IO.unit | |
} | |
} | |
fun sleeper(): IO<Unit> = IO.fx { | |
!effect { println("I am sleepy. I'm going to nap") } | |
!sleep(1.seconds) | |
!effect { println("1 second nap.. Going to sleep some more") } | |
!sleeper() //stack safe recursion, infinitely sleeps | |
} | |
//sampleStart | |
suspend fun main(): Unit = IO.fx { | |
val (_, cancel) = !sleeper() | |
.onCancel(IO.effect { println("\nSomeone made me wake up from my nap...") }) | |
.fork() | |
!sleep(3.seconds) | |
!cancel | |
}.suspended() | |
//sampleEnd | |
/** | |
I am sleepy. I'm going to nap | |
1 second nap.. Going to sleep some more | |
I am sleepy. I'm going to nap | |
1 second nap.. Going to sleep some more | |
I am sleepy. I'm going to nap | |
Someone made me wake up from my nap... | |
**/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment