调用DefaultApplicationLifecycle.stop时,Play Framework应用程序永不停止
我正在开发基于Akka/Play的集群应用程序,其中前端节点可以被群集隔离。在这种情况下,我想退出Play应用程序,以便它可以重新启动并重新加入群集。调用DefaultApplicationLifecycle.stop时,Play Framework应用程序永不停止
我在各种地方阅读,优雅地停止播放应用程序的正确方法是使用ApplicationLifecycle
。我使用依赖注入来获取DefaultApplicationLifecycle
对象,并在出现ThisActorSystemQuarantinedEvent
时调用defaultApplicationLifecycle.stop()
。
我的问题是,应用程序结束了一个奇怪的状态,应用程序仍然运行并侦听HTTP端口,但几乎没有任何工作(所有演员似乎都死了)。看来Future
从未完成,而我在我的应用程序中没有定义stopHook
。我是否应该在某个时候强制拨打System.exit()
?
ApplicationLifecycle
用于注册应用程序停止时执行的挂钩。不过,它不应该被用来停止应用程序。从docs:
这是用来挂钩到Play生命周期事件,特别是当播放停止时。当应用程序被关闭,在倒车时,从它们注册
...
停止钩子执行。由于这种反向排序,只要组件没有收到关闭事件,组件就可以知道使用它所依赖的组件是安全的。
你真正想要的是一个Application
实例。从Application.stop
docs:
停止应用程序。所有停止挂钩运行后,返回的未来将被兑换。
Application.stop
当被调用时,则所有的钩子在ApplicationLifecycle
注册在“从当他们被注册反向”被执行。你可以使用依赖注入也得到Application
实例:
class SomeClass @Inject() (app: Application) {
def somethingHappensThatRequireApplicationToStop() = app.stop()
}
用户仍然可以接收请求,因为您刚刚停止的应用程序,而不是Server
。不能完全肯定,但我认为你可以注入它只是你注入上述应用程序的方式:
import play.core.server.Server
class SomeClass @Inject() (app: Application, server: Server) {
def somethingHappensThatRequireApplicationToStop() = {
app.stop()
server.stop()
}
}
而且,由于它停止服务器强制应用程序停止,你只需要:
import play.core.server.Server
class SomeClass @Inject() (server: Server) {
def somethingHappensThatRequireToStop() = {
server.stop()
}
}
谢谢!我只是想知道为什么我的defaultApplication生命周期的未来从未被称为:S。我会尝试你的建议,谢谢! – CanardMoussant
其实我看到完全相同的行为:应用程序停留在陈旧状态。我想知道如何调试应用程序永不停止的事实。 – CanardMoussant
我想念你的问题的细节。查看关于如何停止服务器的编辑。 – marcospereira
它看起来像所有'DefaultApplicationLifecycle#stop'一样运行所有的停止钩子。你需要自己处理实际的过程。如果未来从未完成,很可能是因为其中一个停止挂钩由于某种原因未能完成(不是因为没有添加),尽管很难说出什么原因或原因。 –