zio-http
zio-http copied to clipboard
Graceful shutdown pattern for the "Getting Started" or the "Simple Server" template...
In anticipation of bootstrapping a new zio-http server, I am using the "Getting Started" template to "grow" towards a solution as I am learning Zio and ZHttp. The current version of the "Getting Started" template looks like this, requiring that I externally "kill" the running process:
import zio.http._
import zio.http.Server
import zio._
object HelloWorld extends ZIOAppDefault {
val app: HttpApp[Any, Nothing] = Http.collect[Request] {
case Method.GET -> !! / "text" => Response.text("Hello World!")
}
override val run =
Server.start(8090, app)
}
I would like to modify app
by adding a "stop" command, and have the server process perform a "graceful shutdown".
val app: HttpApp[Any, Nothing] = Http.collect[Request] {
case Method.GET -> !! / "stop" => ???
case Method.GET -> !! / "text" => Response.text("Hello World!")
}
With what might I replace the ???
to achieve that outcome?
Or, if that isn't possible, what is the simplest pattern I could use to implement the desired "graceful shutdown"?
@chaotic3quilibrium something similar to this should work:
import zhttp._
import zhttp.service.Server
import zhttp.http.{ Request, Response }
import zhttp.http._
override def run =
(for {
shutdownSignal <- Promise.make[Nothing, Unit]
app = Http.collectZIO[Request] {
case Method.GET -> !! / "stop" => shutdownSignal.succeed(()).as(Response.text("shutting down"))
case Method.GET -> !! / "health" => ZIO.succeed(Response.text("Ok"))
}
server <- Server.start(8080, app).fork
_ <- shutdownSignal.await.flatMap(_ => ZIO.sleep(10.seconds) *> server.interrupt)
} yield ()).provide(
EventLoopGroup.auto(0),
ServerChannelFactory.auto
)
Maybe we can add Server#stop
method, which stops the server and releases resources early. Of course, this calls into question what Server#install
should do in the event the server is already shut down.