zio/zio2

Fiber

wefree 2022. 11. 23. 19:36
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
}