如何延迟 ManagedScheduledExecutorService 直到容器未暂停? [英] How to delay ManagedScheduledExecutorService until container is not suspended?

查看:105
本文介绍了如何延迟 ManagedScheduledExecutorService 直到容器未暂停?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调查 javax.enterprise.concurrent.ManagedScheduledExecutorServiceWildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final) 上的使用.>

我的启动 EJB 类似于

import java.time.LocalTime;导入 java.util.concurrent.TimeUnit;导入 javax.annotation.PostConstruct;导入 javax.annotation.Resource;导入 javax.ejb.Singleton;导入 javax.ejb.Startup;导入 javax.enterprise.concurrent.ManagedScheduledExecutorService;@启动@单身人士公共类调度程序{静态最终长 INITIAL_DELAY = 0L;静态最终长周期 = 2L;@资源ManagedScheduledExecutorService调度器;@PostConstruct公共无效初始化(){this.scheduler.scheduleAtFixedRate(this::invokePeriodically, INITIAL_DELAY, PERIOD, TimeUnit.SECONDS);}公共无效invokePeriodically(){System.out.println("@@@@@@@@@@@ - 不要在 prod 中使用 sout " + LocalTime.now());}}

在服务器启动时,我看到以下消息:-

10:15:26,022 错误 [org.jboss.as.ee] (EE-ManagedScheduledExecutorService-default-Thread-1) WFLYEE0110:无法运行计划任务:java.lang.IllegalStateException:WFLYEE0111:由于容器暂停,无法运行计划任务 com.research.Scheduler$$Lambda$932/1222053658@1b50d7a0在 org.jboss.as.ee.concurrent.ControlPointUtils$ControlledScheduledRunnable.run(ControlPointUtils.java:164)在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)在 java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)在 org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.access$201(ManagedScheduledThreadPoolExecutor.java:383)在 org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.run(ManagedScheduledThreadPoolExecutor.java:534)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)在 java.lang.Thread.run(Thread.java:745)在 org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:250)在 org.jboss.as.ee.concurrent.service.ElytronManagedThreadFactory$ElytronManagedThread.run(ElytronManagedThreadFactory.java:78)

当我增加初始延迟时

static final long INITIAL_DELAY = 60L;

服务器启动干净".

是否有任何可用的机制/技术我可以使用(除了猜测我的初始延迟应该多长时间)来始终获得干净的服务器启动并尽快安排我的 EJB?

解决方案

您最好为此目的使用 EJB 计时器.服务器保证在 EJB 服务之前不会触发计时器方法.

您可以在 javax 验证用于创建计时器的 API.ejb.TimerService.

请注意,如果您创建持久计时器,那么服务器将在您重新启动服务器时尝试赶上"错过的触发.

如果它只是一个周期性任务,那么不要创建持久性计时器.

I am investigating the use of javax.enterprise.concurrent.ManagedScheduledExecutorService on WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final).

My Startup EJB resembles

import java.time.LocalTime;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.concurrent.ManagedScheduledExecutorService;

@Startup
@Singleton
public class Scheduler {

    static final long INITIAL_DELAY = 0L;
    static final long PERIOD = 2L;

    @Resource
    ManagedScheduledExecutorService scheduler;

    @PostConstruct
    public void init() {
        this.scheduler.scheduleAtFixedRate(this::invokePeriodically, INITIAL_DELAY, PERIOD, TimeUnit.SECONDS);
    }

    public void invokePeriodically() {
        System.out.println("@@@@@@@@@@ - Don't use sout in prod " + LocalTime.now());
    }

}

On Server Startup I see these messages:-

10:15:26,022 ERROR [org.jboss.as.ee] (EE-ManagedScheduledExecutorService-default-Thread-1) WFLYEE0110: 
Failed to run scheduled task: java.lang.IllegalStateException: 
WFLYEE0111: Cannot run scheduled task com.research.Scheduler$$Lambda$932/1222053658@1b50d7a0 as container is suspended
    at org.jboss.as.ee.concurrent.ControlPointUtils$ControlledScheduledRunnable.run(ControlPointUtils.java:164)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.access$201(ManagedScheduledThreadPoolExecutor.java:383)
    at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.run(ManagedScheduledThreadPoolExecutor.java:534)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:250)
    at org.jboss.as.ee.concurrent.service.ElytronManagedThreadFactory$ElytronManagedThread.run(ElytronManagedThreadFactory.java:78)

When I increase the initial delay

static final long INITIAL_DELAY = 60L;

The server startup is "clean".

Are there any available mechanisms/techniques I can use (other than guessing how long my initial delay should be) to always get a clean server startup and schedule my EJB as soon as possible?

解决方案

You may be better off using an EJB timer for this purpose. The server is guaranteed not to fire timer methods until the EJB is in service.

You can verify the API for creating timers at javax.ejb.TimerService.

Note that if you create persistent timers then the server will try to "catch up" with missed firings when you restart the server.

If it's just a periodic task then don't create persistent timers.

这篇关于如何延迟 ManagedScheduledExecutorService 直到容器未暂停?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆