gpt4 book ai didi

java - Playframework + Akka : how to avoid excuting scheduled tasks executed when shutdown application

转载 作者:行者123 更新时间:2023-12-02 09:07:33 25 4
gpt4 key购买 nike

我在 Play 应用程序服务器启动时启动调度程序,但一旦应用程序关闭,它就会遇到以下代码部分:

// firstDay something like 1 = monday 
private void startScheduler(final ImageService imageService,
final ActorSystem system) {
startImagesCleanupScheduler(imageService, system);
Logger.info("Schedulers started");
}

我的问题是,Runnable block 立即开始执行,而不是仅仅取消任务。

澄清代码:

以下方法启动Scheduler:

private void startImagesCleanupScheduler(ImageService imageService, ActorSystem system) {
system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay
Duration.create(1, TimeUnit.DAYS), //Frequency 1 days
() -> {
int rows = imageService.cleanupInactiveImages();
Logger.info(String.format("%d inactive unused images cleaned from db", rows));

},
system.dispatcher()
);
}

关闭时的日志请注意这里的第一行:

[info] - application - 1 inactive unused images cleaned from db
[info] - application - Shutting down connection pool.
[info] - application - Creating Pool for datasource 'default'
...
[info] - application - Schedulers started
[info] - play.api.Play - Application started (Prod)

您可以看到它执行调度程序,忽略其原始执行时间,然后关闭,然后启动,然后“调度程序启动”。

什么问题,我如何取消调度程序或阻止 Play 在关闭之前运行它?这是 Akka 的错误吗?

我在 OnStartup 中调用 startScheduler,就像以下问题的答案:

java Playframework GlobalSettings deprecation for onStart

编辑:以下是重现问题的最少代码:

首先创建OnStartup类:

@Singleton
public class OnStartup {

@Inject
public OnStartup(final ActorSystem system) {
startScheduler(system);
}

private void startScheduler(final ActorSystem system) {
startImagesCleanupScheduler(system);
Logger.info("Schedulers started");
}

private void startImagesCleanupScheduler(ActorSystem system) {
system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay
Duration.create(1, TimeUnit.DAYS), //Frequency 1 days
() -> {
//int rows = imageService.cleanupInactiveImages();
rows = 1;
Logger.info(String.format("%d inactive unused images cleaned from db", rows ));
},
system.dispatcher()
);
}

}

然后创建模块:

public class OnStartupModule extends AbstractModule {
@Override
public void configure() {
bind(OnStartup.class).asEagerSingleton();
}
}

最后在 application.conf 中启用模块:

play.modules.enabled += "modules.OnStartupModule"

最佳答案

这对于评论来说有点太长了,但我没有测试这种方法,您可能需要调整它。文档说组件会按照创建的相反顺序被销毁。这意味着您可能会在 ActorSystem 关闭之前取消调度程序,因为此类在它之后注册并依赖于它。在您的 OnStartup 类中创建一个像这样的关闭 Hook ,您将在其中取消您的计划。这意味着在 ActorSystem 关闭时,将没有要执行的计划:

@Singleton
public class OnStartup {

private final Cancellable cancellableSchedule;

@Inject
public OnStartup(final ActorSystem system, final ApplicationLifecycle l) {
cancellableSchedule = startScheduler(system);
initStopHook(l);
}

private Cancellable startScheduler(final ActorSystem system) {
return startImagesCleanupScheduler(system);
Logger.info("Schedulers started");
}

private Cancellable startImagesCleanupScheduler(ActorSystem system) {
return system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay
Duration.create(1, TimeUnit.DAYS), //Frequency 1 days
() -> {
//int rows = imageService.cleanupInactiveImages();
rows = 1;
Logger.info(String.format("%d inactive unused images cleaned from db", rows ));
},
system.dispatcher()
);
}

private void initStopHook(ApplicationLifecycle lifecycle) {
lifecycle.addStopHook(() -> {
cancellableSchedule.cancel();
return CompletableFuture.completedFuture(null);
});
}

}

关于java - Playframework + Akka : how to avoid excuting scheduled tasks executed when shutdown application,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37771194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com