gpt4 book ai didi

scala - Zio 运行阻止向后兼容的代码

转载 作者:行者123 更新时间:2023-12-04 21:30:03 25 4
gpt4 key购买 nike

(希望)关于 Scalaz Zio 的简单问题。

我有一些重构为 Zio 的旧代码。我希望该代码的一条路径保持原样:

  • 同步
  • 阻塞
  • 在当前线程上(这是一个硬性要求)

  • 我如何运行 IO这样它的行为就像旧的阻塞代码?

    我目前使用:
      private lazy val blockingRts = new RTS {}
    def runBlocking[E, A](io: IO[E, A]): Either[E, A] = {
    blockingRts.unsafeRun(io.attempt)
    }

    它似乎可以解决问题,但我不确定这是正确的。这是 100% 向后兼容旧代码吗?

    最佳答案

    好的,我终于深入了解并实现了一些似乎满足我的要求的东西:

      /**
    * Executes the IO synchronous and blocking on the current thread, thus running an IO
    * without any of the advantages of IO. This can be useful for maintaining backwards compatibility.
    * Rethrows any exception that was not handled by the IO's error handling.
    */
    @throws
    def runLegacy[E, A](io: IO[E, A]): Either[E, A] = {
    syncBlockingRunTimeSystem.unsafeRunSync[Nothing, Either[E, A]](io.either) match {
    case Exit.Success(v) => v
    case Exit.Failure(Cause.Die(exception)) => throw exception
    case Exit.Failure(Cause.Interrupt) => throw new InterruptedException
    case Exit.Failure(fail) => throw FiberFailure(fail)
    }
    }

    private lazy val syncBlockingRunTimeSystem = Runtime(
    (),
    PlatformLive.fromExecutor(new Executor {
    override def yieldOpCount: Int = Int.MaxValue
    override def metrics: Option[ExecutionMetrics] = None
    override def submit(runnable: Runnable): Boolean = {
    runnable.run()
    true
    }
    override def here: Boolean = true
    })
    )

    我还写了几个测试:
      "runLegacy" should {
    "run synchronous code in blocking fashion on current thread" in {
    var runCount = 0
    val io = IO.succeedLazy { runCount += 1 }
    .map { _ => runCount +=1 }
    .flatMap { _ =>
    runCount += 1
    IO.effect {
    runCount += 1
    Thread.currentThread()
    }
    }

    runCount shouldBe 0
    runLegacy(io) shouldBe Right(Thread.currentThread())
    runCount shouldBe 4
    }

    "run parallel code sequentially on current thread" in {
    val ios = (1 to 500).map { i => IO.succeedLazy { i } }
    runLegacy(IO.reduceAll(IO.succeed(0), ios) {
    case (a, b) => a + b
    }) shouldBe Right((500 * 501) / 2)
    }

    "run many flatMaps without overflowing" in {
    var runCount = 0
    val io = IO.succeedLazy { runCount += 1 }
    val manyIo = (1 to 9999).foldLeft(io) { case (acc, _) => acc.flatMap { _ => io } }
    runLegacy(manyIo)
    runCount shouldBe 10000
    }

    case object TestException extends Throwable

    "handle sync blocking errors" in {
    case object TestException extends Throwable
    runLegacy(IO.effect(throw TestException)) shouldBe Left(TestException)
    }

    "rethrow unhandled exceptions" in {
    assertThrows[TestException.type] {
    runLegacy(IO.succeedLazy(throw TestException))
    }
    }
    }

    关于scala - Zio 运行阻止向后兼容的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55380840/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com