cats-effect
cats-effect copied to clipboard
Potential inconsistency between joinWithNever and docs
Hi there,
In the docs for the the Spawn
typeclass at the very end it states:
In English, the semantics of this are as follows:
If the child fiber completed successfully, produce its result If it errored, re-raise the error within the current fiber If it canceled, attempt to self-cancel, and if the self-cancelation fails, deadlock Sometimes this is an appropriate semantic, and the cautiously-verbose joinWithNever function implements it for you.
However, the joinWithNever
implementation doesn't look like it actually makes any attempts at self cancellation and I think I've confirmed this with a small test app.
object FunTest extends IOApp.Simple {
override val run: IO[Unit] = for {
_ <- IO.println("Starting")
child = IO.println("Starting child...") >>
IO.sleep(1.second) >>
IO.canceled >>
IO.sleep(1.second) >>
IO.println("Child completed")
childFiber <- child.start
dependentChild <- childFiber.joinWithNever.as("I managed to return something").start
result <- dependentChild
.joinWith(IO.pure("I was cancelled"))
.timeoutTo(3.seconds, "I waited too long :(".pure[IO])
_ <- IO.println(s"result is $result")
} yield ()
}
which outputs the following to console
Starting
Starting child...
result is I waited too long :(
Process finished with exit code 0