私は初めて ZIO を使用しており、https://github.com/guizmaii/scala-tapir-http4s-zio/blob/master/src/main/scala/example/HttpApp.scalaのボイラープレート スタブから始めました。 ZIO バージョン 1.0.0-RC17 を使用して、Tapir を含む http4s Blaze サーバーをセットアップして実行します。それはうまくいきましたが、後でバージョン 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]
終了コードの int を ExitCode オブジェクトに置き換えると、コードはコンパイルされますが、この後、Blaze サーバーはアプリの初期化や終了の防止を行っていないようです。終了コード0で終了しました。
明らかに何かが欠けています。古い環境システムから Has[A] に基づく新しいシステムへの移行に関する情報は見たことがありません。Blaze サーバーが再び実行されるように、このボイラープレートを修正するにはどうすればよいですか?