我第一次使用 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, Throwable, *]]
.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
}
}
由于引入了 Has[A],这在 1.0.3 中不起作用。编译器现在抱怨你不能从最终类 Has 继承,所以你不能调用新的时钟。
我试图通过替换它来解决这个问题
prog = server.provideSomeLayer[ZEnv]
并用 ExitCode 对象替换退出代码整数,这使得代码编译,但在此之后 Blaze 服务器似乎没有初始化或阻止应用程序的终止。它刚刚以退出代码 0 结束。
显然这里缺少一些东西,而且我还没有看到任何关于从旧环境系统转移到基于 Has[A] 的新系统的信息。如何修复此样板文件以便 Blaze 服务器再次运行?