I have a running Akka HTTP application and I want to shut it down.
Pressing Ctrl + C in SBT does not work for me (my shell is currently Git Bash for Windows).
What's the recommended way of shutting down an Akka app gracefully?
To start the coordinated shutdown process you can either invoke terminate() on the ActorSystem , or run on the CoordinatedShutdown extension and pass it a class implementing CoordinatedShutdown. Reason. for informational purposes: Scala.
Akka HTTP is a series of modules that implement a server-side and client-side HTTP stack. It is a general toolkit for providing and consuming HTTP-based services. Any interaction with a browser is part of these modules; however, it is not Akka HTTP's primary concern.
It's not a web-framework but rather a more general toolkit for providing and consuming HTTP-based services. While interaction with a browser is of course also in scope it is not the primary focus of Akka HTTP.
Taking inspiration from this thread, I added a route to my application that shuts down the application:
def shutdownRoute: Route = path("shutdown") {
Http().shutdownAllConnectionPools() andThen { case _ => system.terminate() }
complete("Shutting down app")
}
where system
is the app's ActorSystem.
Given this route, I can now shut down my application with
curl http://localhost:5000/shutdown
Edit:
Being able to shut down a server remotely is not a good idea for production code. In the comments, Henrik pointed to a different way that shuts down the server by hitting Enter in the SBT console:
StdIn.readLine()
// Unbind from the port and shut down when done
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
For context, I put the above code at the end of server initialization:
// Gets the host and a port from the configuration
val host = system.settings.config.getString("http.host")
val port = system.settings.config.getInt("http.port")
implicit val materializer = ActorMaterializer()
// bindAndHandle requires an implicit ExecutionContext
implicit val ec = system.dispatcher
import akka.http.scaladsl.server.Directives._
val route = path("hi") {
complete("How's it going?")
}
// Starts the HTTP server
val bindingFuture: Future[ServerBinding] =
Http().bindAndHandle(route, host, port)
val log = Logging(system.eventStream, "my-application")
bindingFuture.onComplete {
case Success(serverBinding) =>
log.info(s"Server bound to ${serverBinding.localAddress}")
case Failure(ex) =>
log.error(ex, "Failed to bind to {}:{}!", host, port)
system.terminate()
}
log.info("Press enter key to stop...")
// Let the application run until we press the enter key
StdIn.readLine()
// Unbind from the port and shut down when done
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With