Scala 为什么它会立即终止?

Scala 为什么它会立即终止?,scala,akka,akka-stream,akka-http,Scala,Akka,Akka Stream,Akka Http,我有以下代码,我想理解,为什么在执行时它会立即停止: import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer import scala.io.StdIn

我有以下代码,我想理解,为什么在执行时它会立即停止:

    import akka.actor.ActorSystem
    import akka.http.scaladsl.Http
    import akka.http.scaladsl.model._
    import akka.http.scaladsl.server.Directives._
    import akka.stream.ActorMaterializer
    import scala.io.StdIn

    object WebServer {
      def main(args: Array[String]) {

        implicit val system = ActorSystem("my-system")
        implicit val materializer = ActorMaterializer()
        // needed for the future flatMap/onComplete in the end
        implicit val executionContext = system.dispatcher

        val route =
          path("hello") {
            get {
              complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
            }
          }

        val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
        bindingFuture
          .flatMap(_.unbind()) // trigger unbinding from the port
          .onComplete(_ => system.terminate()) // and shutdown when done
      }
    }
然后它永远运行,直到我终止它。 问题是,为什么没有

bindingFuture
  .flatMap(_.unbind()) // trigger unbinding from the port
  .onComplete(_ => system.terminate()) // and shutdown when done 
应用程序不会终止?

在这两种情况下,您的绑定都将完成。如果你坚持

bindingFuture
  .flatMap(_.unbind()) // trigger unbinding from the port
  .onComplete(_ => system.terminate()) // and shutdown when done 
然后在服务器正在侦听时立即解除绑定并终止get run,这会导致程序立即完成

如果省略了该代码,那么程序将一直运行,直到所有线程都完成为止。因为actor系统在后台运行线程,并且您永远不会终止它,所以这种情况永远不会发生,您必须杀死程序才能停止它

一种在任何按键时优雅地关机的方法是使用从

在这种情况下,StdIn.readLine将阻塞主线程,直到按下一个键,此时actor系统和http服务器将关闭

如果您想等待自定义事件而不是按键,您可以简单地等待自定义事件,如下所示:

// Just build a Future that will get completed when you want to shutdown
// This can be done manually using a `Promise[Unit]`, but you might also be using 
// a library that will give you a Future to wait on.
val myFuture: Future[Unit] = ??? 
myFuture.flatMap(_ => bindingFuture)
    .flatMap(_.unbind())
    .onComplete(_ => system.terminate())
在这两种情况下,您的绑定都将完成。如果你坚持

bindingFuture
  .flatMap(_.unbind()) // trigger unbinding from the port
  .onComplete(_ => system.terminate()) // and shutdown when done 
然后在服务器正在侦听时立即解除绑定并终止get run,这会导致程序立即完成

如果省略了该代码,那么程序将一直运行,直到所有线程都完成为止。因为actor系统在后台运行线程,并且您永远不会终止它,所以这种情况永远不会发生,您必须杀死程序才能停止它

一种在任何按键时优雅地关机的方法是使用从

在这种情况下,StdIn.readLine将阻塞主线程,直到按下一个键,此时actor系统和http服务器将关闭

如果您想等待自定义事件而不是按键,您可以简单地等待自定义事件,如下所示:

// Just build a Future that will get completed when you want to shutdown
// This can be done manually using a `Promise[Unit]`, but you might also be using 
// a library that will give you a Future to wait on.
val myFuture: Future[Unit] = ??? 
myFuture.flatMap(_ => bindingFuture)
    .flatMap(_.unbind())
    .onComplete(_ => system.terminate())