How to Interop with Future?
Scala Future​
Basic interoperability with Scala's Future is now provided by ZIO, and does not require a separate module.
From Future​
Scala's Future can be converted into a ZIO effect with ZIO.fromFuture:
def loggedFuture[A](future: ExecutionContext => Future[A]): UIO[Task[A]] = {
ZIO.fromFuture { implicit ec =>
future(ec).flatMap { result =>
Future(println("Future succeeded with " + result)).map(_ => result)
}
}
}
Scala's Future can also be converted into a Fiber with Fiber.fromFuture:
def futureToFiber[A](future: => Future[A]): Fiber[Throwable, A] =
Fiber.fromFuture(future)
This is a pure operation, given any sensible notion of fiber equality.
To Future​
A ZIO Task effect can be converted into a Future with ZIO#toFuture:
def taskToFuture[A](task: Task[A]): UIO[Future[A]] =
task.toFuture
Because converting a Task into an (eager) Future is effectful, the return value of ZIO#toFuture is an effect. To actually begin the computation, and access the started Future, it is necessary to execute the effect with a runtime.
A ZIO Fiber can be converted into a Future with Fiber#toFuture:
def fiberToFuture[A](fiber: Fiber[Throwable, A]): UIO[Future[A]] =
fiber.toFuture
Run to Future​
You can call .unsafe.runToFuture on an instance of Runtime to execute a ZIO effect asynchronously and return a Future that will be completed when the execution of the effect is complete.
import zio.{Runtime, Task, Unsafe}
...
val zio: Task[String] = ...
val runtime = Runtime.default
val fut: Future[String] = Unsafe.unsafe { implicit unsafe =>
runtime.unsafe.runToFuture(zio)
}