Skip to content

Instantly share code, notes, and snippets.

@monadplus
Last active March 13, 2019 19:15
Show Gist options
  • Save monadplus/01d6e81362335735445a45aa36da8782 to your computer and use it in GitHub Desktop.
Save monadplus/01d6e81362335735445a45aa36da8782 to your computer and use it in GitHub Desktop.
await
import cats._
import cats.implicits._
import cats.effect._
import cats.effect.concurrent.Deferred
import cats.effect.implicits._
import scala.concurrent.duration._
object Await extends IOApp {
def await[F[_]: Concurrent, A](fa: F[A]): F[(F[Option[Either[Throwable, A]]], CancelToken[F])] =
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).attempt.void
case _ => ().pure[F]
}
action.start.bracketCase( fiber =>
(result.get -> fiber.cancel).pure[F]
) {
case (fiber, ExitCase.Canceled) => fiber.cancel
case (_, _) => ().pure[F]
}
}
def cancelable[F[_]: Sync](implicit timer: Timer[F]): F[Int] =
timer.sleep(2.seconds) *> 10.pure[F]
override def run(args: List[String]): IO[ExitCode] =
for {
(result, cancelToken) <- await(cancelable[IO])
_ <- cancelToken
r <- result
_ <- IO(println(s"Result $r"))
} yield ExitCode.Success
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment