为什么会立即终止?
Why does it terminate immediatly?
我有以下代码,想了解为什么它在我执行时立即停止:
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
}
}
如您所见,它是一个简单的 Web 应用程序,不应停止到 运行。
但是当我删除以下代码时:
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
在这两种情况下都完成了。如果你保持
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
然后 unbind
和 terminate
得到 运行 一旦服务器正在侦听,这会导致您的程序立即完成。
如果您省略该代码,那么您的程序将保持 运行ning 直到它的所有线程都完成。因为 actor 系统是后台的 运行 个线程,你永远不会终止它,所以这永远不会发生,你必须终止你的程序才能停止它。
一种在任何按键下正常关机的方法是使用这个(取自official documentation)
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine() // let it run until user presses return
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
在这种情况下,StdIn.readLine()
将阻塞主线程,直到按下某个键,此时 actor 系统和 http 服务器将关闭。
如果您想等待自定义 "event" 而不是按键,您可以像这样简单地等待自定义 Future
:
// 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())
我有以下代码,想了解为什么它在我执行时立即停止:
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
}
}
如您所见,它是一个简单的 Web 应用程序,不应停止到 运行。
但是当我删除以下代码时:
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
在这两种情况下都完成了。如果你保持
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
然后 unbind
和 terminate
得到 运行 一旦服务器正在侦听,这会导致您的程序立即完成。
如果您省略该代码,那么您的程序将保持 运行ning 直到它的所有线程都完成。因为 actor 系统是后台的 运行 个线程,你永远不会终止它,所以这永远不会发生,你必须终止你的程序才能停止它。
一种在任何按键下正常关机的方法是使用这个(取自official documentation)
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine() // let it run until user presses return
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
在这种情况下,StdIn.readLine()
将阻塞主线程,直到按下某个键,此时 actor 系统和 http 服务器将关闭。
如果您想等待自定义 "event" 而不是按键,您可以像这样简单地等待自定义 Future
:
// 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())