Как вручную заставить @Schedule отработать ещё раз?

У меня есть демон, который запускается раз в сутки в три часа утра и выполняет некоторые операции над объектами. Количество объектов, обрабатываемых демоном за раз, ограничивается сотней:

@AccessTimeout(0)
@Schedule(persistent = false, hour = "3")
private void doSomething() {
    int limit = 100;
    handleObjects(limit);
}

Я хочу сделать следующее поведение. Допустим, демон обрабатывает свои сто объектов и видит, что осталось ещё 700 необработанных объектов. И я хочу, чтобы вместо следующего включения через сутки он бы отработал через десять минут. И так, пока объекты не кончатся. После того, как они кончатся, демон должен заснуть до следующих трёх утра. То есть мне нужно, чтобы демон выглядел как-то так:

@AccessTimeout(0)
@Schedule(persistent = false, hour = "3")
private void doSomething() {
    int limit = 100;
    handleObjects(limit);
    if (getUnhandledObjectsTotalAmount() > 0) {
        runThisDaemonAfterTenMinutes();
    }
}

Каким образом я могу добиться подобного поведения?


Ответы (1 шт):

Автор решения: Дмитрий

Вариантов много. Я бы просто заюзал что-то типа экзекьютеров. Они простые в реализации

private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

@AccessTimeout(0)
@Schedule(persistent = false, hour = "3")
private void doSomething() {
    int limit = 100;
    handleObjects(limit);
    if (getUnhandledObjectsTotalAmount() > 0) {
        executorService.schedule(() -> doSomething(), 10, TimeUnit.MINUTES);
    }
}

Но в целом выполнения задач по расписанию - плохое решение и оправдано оно в единичных случаях (например , если вам нужно опрашивать стороннюю API , на которую повлиять вы никак не можете и других вариантов получить обновленные данные у вас нет). В остальных случаях одним из возможных хороших решений будет паттерн слушатель. Когда мы говорим о чем-то событийном, то есть 2 варианта развития событий: 1) событие происходит и все, кто хотят о нем знать, спрашивают того, кто знает (это ваш случай и прочие подобные случаи, где используют задачи по расписанию). минус - непонятно как часто запрашивать данные. перегибы в любую стороны - не есть хорошо, а золотой средины нет. 2) тот, кто знает о событии, оповещает всех, кто хочет о нем знать (по сути и есть паттерн слушатель). Аналогия из жизни - больница, где лежат больные. 1 вариант развития событий - медсестра постоянно бегает по палатам и смотрит, не стало ли кому-то плохо. 2 вариант развития событий - поставить тревожные кнопки больным, тогда медсестра бежит только на вызов. Что эффективней , как по мне, вполне очевидно

→ Ссылка