播放应用程序关闭时未调用停止挂钩
Stop Hook Is Not Being Called When Play Application Is Shutting Down
我正在使用 Play Framework 2.5.5 开发应用程序,但在向我的 class 添加停止挂钩时遇到了问题。我有一个名为 Broom
的 class,如下所示安排清洁工作。
@ImplementedBy(classOf[Broom])
trait AbstractBroom
@Singleton
class Broom @Inject()(ActorSystem: ActorSystem,
ApplicationLifecycle: ApplicationLifecycle,
Conf: AbstractConf) extends AbstractBroom with Logging {
private val enabled: Boolean = Conf.getBoolean("enabled", defaultValue = true)
private val initialDelay: FiniteDuration = Conf.getFiniteDuration("initialDelay", FiniteDuration(10, TimeUnit.SECONDS))
private val interval: FiniteDuration = Conf.getFiniteDuration("interval", FiniteDuration(1, TimeUnit.DAYS))
private val actor: ActorRef = ActorSystem.actorOf(Props(new BroomActor(Conf)), BroomActor.actorName)
private val cancellable: Option[Cancellable] = {
if (enabled) {
val firstRun: LocalDateTime = LocalDateTime.now.plusSeconds(interval.toSeconds).withNano(0)
Log.warn(s"Starting Broom scheduled to $firstRun...")
val c: Cancellable = ActorSystem.scheduler.schedule(
initialDelay,
interval,
actor,
Wipe
)
Option(c)
} else {
None
}
}
ApplicationLifecycle.addStopHook {
() =>
actor ! PoisonPill
cancellable.foreach {
c: Cancellable =>
Log.warn("Shutting down Broom...")
c.cancel()
}
ActorSystem.terminate()
}
}
它只是定期向 BroomActor
发送 Wipe
消息,因此它可以对旧数据执行一些清理。因为我想在应用程序关闭时停止 Broom
,所以我向 ApplicationLifecycle
添加了一个依赖项并调用了 addStopHook
方法。
为了在应用程序启动时启动 Broom
,我在 com.example
包中有一个名为 Modules
的 class,如下所示
class Modules extends AbstractModule {
override def configure(): Unit = {
bind(classOf[Broom]).asEagerSingleton()
}
}
在我的配置中引用如下。
play.modules.enabled += "com.example.Modules"
我在应用程序启动时看到启动消息,但在关闭时我没有看到停止消息。我注意到即使我的应用程序不是 运行,清理实际上仍在后台继续。我想我可能会泄露一些东西。
我在我的另一个 Play 2.5.4 项目 https://github.com/mehmetakiftutuncu/quupNotificationsServer 中为 Heartbeat
class 设置了几乎相同的配置,它可以正常工作。我在这里做错了什么?
这是 Play 2.5.5 的错误,请参阅 this issue。在 2.5.6 发布之前,您最好坚持使用 2.5.4。
我正在使用 Play Framework 2.5.5 开发应用程序,但在向我的 class 添加停止挂钩时遇到了问题。我有一个名为 Broom
的 class,如下所示安排清洁工作。
@ImplementedBy(classOf[Broom])
trait AbstractBroom
@Singleton
class Broom @Inject()(ActorSystem: ActorSystem,
ApplicationLifecycle: ApplicationLifecycle,
Conf: AbstractConf) extends AbstractBroom with Logging {
private val enabled: Boolean = Conf.getBoolean("enabled", defaultValue = true)
private val initialDelay: FiniteDuration = Conf.getFiniteDuration("initialDelay", FiniteDuration(10, TimeUnit.SECONDS))
private val interval: FiniteDuration = Conf.getFiniteDuration("interval", FiniteDuration(1, TimeUnit.DAYS))
private val actor: ActorRef = ActorSystem.actorOf(Props(new BroomActor(Conf)), BroomActor.actorName)
private val cancellable: Option[Cancellable] = {
if (enabled) {
val firstRun: LocalDateTime = LocalDateTime.now.plusSeconds(interval.toSeconds).withNano(0)
Log.warn(s"Starting Broom scheduled to $firstRun...")
val c: Cancellable = ActorSystem.scheduler.schedule(
initialDelay,
interval,
actor,
Wipe
)
Option(c)
} else {
None
}
}
ApplicationLifecycle.addStopHook {
() =>
actor ! PoisonPill
cancellable.foreach {
c: Cancellable =>
Log.warn("Shutting down Broom...")
c.cancel()
}
ActorSystem.terminate()
}
}
它只是定期向 BroomActor
发送 Wipe
消息,因此它可以对旧数据执行一些清理。因为我想在应用程序关闭时停止 Broom
,所以我向 ApplicationLifecycle
添加了一个依赖项并调用了 addStopHook
方法。
为了在应用程序启动时启动 Broom
,我在 com.example
包中有一个名为 Modules
的 class,如下所示
class Modules extends AbstractModule {
override def configure(): Unit = {
bind(classOf[Broom]).asEagerSingleton()
}
}
在我的配置中引用如下。
play.modules.enabled += "com.example.Modules"
我在应用程序启动时看到启动消息,但在关闭时我没有看到停止消息。我注意到即使我的应用程序不是 运行,清理实际上仍在后台继续。我想我可能会泄露一些东西。
我在我的另一个 Play 2.5.4 项目 https://github.com/mehmetakiftutuncu/quupNotificationsServer 中为 Heartbeat
class 设置了几乎相同的配置,它可以正常工作。我在这里做错了什么?
这是 Play 2.5.5 的错误,请参阅 this issue。在 2.5.6 发布之前,您最好坚持使用 2.5.4。