IO.unit.handleError(...) >> boom
, which doesn't handle errors in boom
try {
thing
} catch {
...
}
boom
doesn't handle errors in boom
readFile.timeout(5.seconds)
(assuming that your readfile implementation is cancelable)
.join
if you haven't called cancel
. In the simplest case this is an if, in more complicated cases you might need some coordination between the interrupter and the joiner
Deferred[Option[Thing]]
bracketCase
or guaranteeCase
the started operation so that it puts None
on that Deferred
when it gets cancelled
def await[F[_]: Concurrent, A](fa: F[A]): F[(F[Option[Either[Throwable, A]]], F[Unit])] =
Deferred[F, Option[Either[Throwable, A]]].flatMap { result =>
val action = {
fa.attempt.flatMap(r => result.complete(r.some).uncancelable)
}.guaranteeCase {
case ExitCase.Canceled => result.complete(None)
case _ => ().pure[F]
}
action.start.bracketCase(fiber => result.get.pure[F] -> fiber.cancel){
case (fiber, ExitCase.Canceled) => fiber.cancel
case (_, _) => ().pure[F]
}
}
release
should not be possible to cancel, but I'm not sure how to ensure that