如何延迟 ManagedScheduledExecutorService 直到容器未暂停?
How to delay ManagedScheduledExecutorService until container is not suspended?
我正在调查 javax.enterprise.concurrent.ManagedScheduledExecutorService
在 WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final)
上的使用情况。
我的启动 EJB 类似于
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());
}
}
在服务器启动时我看到这些消息:-
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$$Lambda2/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.access1(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)
当我增加初始延迟时
static final long INITIAL_DELAY = 60L;
服务器启动是"clean"。
是否有可用的 mechanisms/techniques 我可以使用(除了猜测我的初始延迟应该多长时间)来始终获得干净的服务器启动并尽快安排我的 EJB?
您最好为此目的使用 EJB 计时器。在 EJB 投入使用之前,服务器保证不会触发计时器方法。
您可以在 javax.ejb.TimerService 验证 API 用于创建计时器。
请注意,如果您创建持久性计时器,那么当您重新启动服务器时,服务器将尝试 "catch up" 错过触发。
如果它只是一个周期性任务,那么不要创建持久性计时器。
回答这个问题有点晚了,但您可以在方法声明上方使用内置的 EE 注释:@Schedule
,而不是依赖另一个 API。它提供了在内部确定超时和持久性的能力。
我正在调查 javax.enterprise.concurrent.ManagedScheduledExecutorService
在 WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final)
上的使用情况。
我的启动 EJB 类似于
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());
}
}
在服务器启动时我看到这些消息:-
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$$Lambda2/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.access1(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)
当我增加初始延迟时
static final long INITIAL_DELAY = 60L;
服务器启动是"clean"。
是否有可用的 mechanisms/techniques 我可以使用(除了猜测我的初始延迟应该多长时间)来始终获得干净的服务器启动并尽快安排我的 EJB?
您最好为此目的使用 EJB 计时器。在 EJB 投入使用之前,服务器保证不会触发计时器方法。
您可以在 javax.ejb.TimerService 验证 API 用于创建计时器。
请注意,如果您创建持久性计时器,那么当您重新启动服务器时,服务器将尝试 "catch up" 错过触发。
如果它只是一个周期性任务,那么不要创建持久性计时器。
回答这个问题有点晚了,但您可以在方法声明上方使用内置的 EE 注释:@Schedule
,而不是依赖另一个 API。它提供了在内部确定超时和持久性的能力。