Как отложить ManagedScheduledExecutorService, пока контейнер не будет приостановлен?

Я расследую использование javax.enterprise.concurrent.ManagedScheduledExecutorService на WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final),

Мой Startup 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$$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)

Когда я увеличиваю начальную задержку

static final long INITIAL_DELAY = 60L;

Запуск сервера "чистый".

Существуют ли какие-либо доступные механизмы / методы, которые я могу использовать (кроме предположения о том, какой должна быть моя первоначальная задержка), чтобы всегда запускать чистый сервер и планировать свой EJB как можно скорее?

1 ответ

Решение

Вам может быть лучше использовать таймер EJB для этой цели. Сервер гарантированно не будет запускать методы таймера, пока EJB не будет в работе.

Вы можете проверить API для создания таймеров в javax.ejb.TimerService.

Обратите внимание, что если вы создаете постоянные таймеры, то сервер попытается "догнать" пропущенные срабатывания при перезагрузке сервера.

Если это просто периодическая задача, не создавайте постоянные таймеры.

Немного поздно ответить на этот вопрос, но вместо того, чтобы полагаться на другой API, вы можете использовать встроенную аннотацию EE: @Scheduleнад объявлением вашего метода. Он предоставляет возможность определять тайм-ауты и постоянство внутри.

Другие вопросы по тегам