ZIO 1.0.3 改变了环境的工作方式,现在 http4s Blaze 将无法运行

问题描述

我是第一次使用 ZIO,我从 https://github.com/guizmaii/scala-tapir-http4s-zio/blob/master/src/main/scala/example/HttpApp.scala 的样板存根开始,它使用 ZIO 版本 1.0.0-RC17 来设置和运行 http4s Blaze 服务器,包括 Tapir。效果很好,但后来我尝试更新到 1.0.3 版,以便我使用最新版本,但该版本与此存根中的代码不兼容。具体:

这是定义服务器的代码(剪掉了一些不相关的路由线):

val prog: ZIO[ZEnv,Throwable,Unit] = for {
  conf <- ZIO.effect(ApplicationConf.build().orThrow())
  _ <- putStrLn(conf.toString)
  server = ZIO.runtime[AppEnvironment].flatMap { implicit rts =>
    val apiRoutes = new ApiRoutes[AppEnvironment]()
    val allTapirRoutes                           = apiRoutes.getRoutes.foldK
    val httpApp: HttpApp[RIO[AppEnvironment,*]] = (allTapirRoutes).orNotFound
    val httpAppExtended = Logger.httpApp(logHeaders = true,logBody = true)(httpApp)
    BlazeServerBuilder[ZIO[AppEnvironment,*]]
      .bindHttp(conf.port.port.value,conf.server.value)
      .withHttpApp(httpAppExtended)
      .withoutBanner
      .withSocketKeepAlive(true)
      .withTcpNoDelay(true)
      .serve
      .compile[RIO[AppEnvironment,*],RIO[AppEnvironment,ExitCode]
      .drain
  }
  prog <- server.provideSome[ZEnv] { currentEnv =>
    new Clock {
      override val clock: Clock.Service[Any] = currentEnv.clock
    }
  }
} yield prog

prog.foldM(h => putStrLn(h.toString).as(1),_ => ZIO.succeed(0))

这是 run() 方法的主体。运行此代码永远不会导致应用程序以代码 0 退出,因为 Blaze 服务器会按预期阻止终止。问题是这个片段:

prog <- server.provideSome[ZEnv] { currentEnv =>
    new Clock {
      override val clock: Clock.Service[Any] = currentEnv.clock
    }
  }

这在 1.0.3 中不起作用,因为引入了 Has[A]。编译器现在抱怨您无法从 final 类 Has 继承,因此您无法调用新的 Clock。

我试图通过将其替换为

来解决此问题
prog = server.provideSomeLayer[ZEnv]

并用 ExitCode 对象替换退出代码整数,这使得代码可以编译,但在此之后,Blaze 服务器似乎没有初始化或阻止应用程序终止。它刚刚结束,退出代码为 0。

显然这里缺少一些东西,我还没有看到任何关于从旧环境系统转移到基于 Has[A] 的新系统的信息。如何修复此样板文件,以便 Blaze 服务器再次运行?

解决方法

如果您对模板tapir-zio-http4s 项目感兴趣,我建议使用tapir repo 中的一个:https://github.com/softwaremill/tapir/blob/master/examples/src/main/scala/sttp/tapir/examples/ZioExampleHttp4sServer.scala

保证总是针对最新的 Tapir 进行编译(因为它是项目的一部分)。

也是我最近个人使用的。成功了。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...