こういう良い記事がある。しかしこの構成を実行すると、SIGINTを受け付けないサーバになってしまう(以下引用)。
object Main extends IOApp { val echo = HttpRoutes.of[IO] { case GET -> Root / "echo" / arg => Ok(arg) }.orNotFound def run(args: List[String]):IO[ExitCode] = EmberServerBuilder .default[IO] // EmberServerBuilder[cats.effect.IO] .withHost(ipv4"0.0.0.0") .withPort(port"8080") .withHttpApp(echo) .build // Resource[IO,Server] .useForever // IO[Nothing] .as(ExitCode.Success) // IO[ExitCode] }
当初、自分はuseForever
が何か奇妙なことをしていてSIGINTを受け付けていないだけかと思っていたが、ソースコードを探しているうちに、単にSIGINTを受け付けてから30秒タイムアウト期間を設けているだけだとわかった。
上掲のコードでdefault
メソッドを呼び出すことでデフォルト設定がサーバに適用されるのだが、この中にはシャットダウンタイムアウトも含まれていて、その値が30秒に設定されている。
しかし、シャットダウンを開始したことくらい標準出力に吐き出してほしいという気持ちもあるのだが、基本的に言われなければやらないミニマルなライブラリで、そこが良さでもあるので、難しいな、と思った。これを発見するのに1ヶ月くらいかかった。加えて、コネクションがないのが明白であればシャットダウンをすぐ行えばよいはず。 Blazeなどの他のサーバ実装を使うと*1このような事は発生しないかもしれない。
*1:http4sはいくつものバックエンド実装を使うことができる。NettyやJettyも使える