import zio._
object FiberTest extends zio.ZIOAppDefault {
// fork 를 사용하지 않으면 동일한 thread 에서 실행됨
def runOnAnotherThread[R, E, A](zio: ZIO[R, E, A]) =
for {
fib <- zio.fork // zio.fork: URIO[R, Fiber[E, A]]
result <- fib.join // fiber.join: IO[E, A]
} yield result
def runOnAnotherThread_v2[R, E, A](zio: ZIO[R, E, A]) =
for {
fib <- zio.fork
result <- fib.await
} yield result match {
case Exit.Success(value) => s"Success with $value"
case Exit.Failure(cause) => s"Failed with $cause"
}
// poll - peek a result of the fiber RIGHT NOW, without blocking
def peekFiber: ZIO[Any, Nothing, Option[Exit[Nothing, RuntimeFlags]]] =
for {
fib <- ZIO.succeed {
Thread.sleep(1000)
42
}.fork
result <- fib.poll // 1초를 기다리지 않고(non-blocking) 바로 리턴, 아직 완료 안되었으므로 None 값으로 리턴
} yield result
// compose fibers - zip
val zippedFibers: ZIO[Any, Nothing, (String, String)] = for {
fib1 <- ZIO.succeed("Result from fiber 1").fork
fib2 <- ZIO.succeed("Result from fiber 2").fork
fib = fib1.zip(fib2)
tuple <- fib.join
} yield tuple
// compose fibers - orElse
val chainedFiber: ZIO[Any, Nothing, String] = for {
fib1 <- ZIO.fail("not good!").fork
fib2 <- ZIO.succeed("it's good").fork
fib = fib1.orElse(fib2)
result <- fib.join
} yield result
override def run = chainedFiber
}