#java #playframework
#java #playframework
Вопрос:
У меня есть игра! Задание фреймворка, которое выполняется каждые 30 секунд:
@Every("30s")
public class MyJob extends Job { ... }
Это задание выполняет несколько функций, таких как чтение электронных писем и запись в базу данных. Однако возможно, что задание может не завершиться в течение 30 секунд. Если задание занимает больше 30 секунд, я хотел бы завершить последующее задание, которое пытается запуститься, пока исходное задание все еще выполняется. Есть ли способ сделать это? или даже приостановить последующее задание, пока исходное не завершит свою работу?
Ответ №1:
насколько я знаю, вам не нужно завершать работу. Я создал задание, которое должно было выполняться каждую минуту, но в некоторых сценариях оно могло (потенциально) выполняться дольше минуты.
Я провел некоторые тесты и имейте в виду, что, возможно, я выполнил их неправильно, но Play не запускает новый экземпляр задания, если оно уже запущено. Как только задание завершится, оно запустит следующий экземпляр в ожидаемое время. Считайте, что Play обрабатывает задания как «Одиночные», только 1 из данного типа активен в данный момент времени.
Итак, нет, вам не нужно ничего отключать или проверять. Потрясающе, не так ли? 😉
Комментарии:
1. да, похоже, что это действительно так! Спасибо, отец.
Ответ №2:
Вы могли бы использовать ReentrantLock
для предотвращения одновременного запуска нескольких экземпляров. Что-то вроде этого:
@Every("30s")
public class MyJob extends Job {
/**
* Used to avoid running multiple instances of this job simultaneously.
*/
private static final ReentrantLock runningLock = new ReentrantLock();
@Override
public void doJob() {
// sb: try to acquire the lock. if the lock is in use, then just
// return immediately, because this job is already running.
// wait a half second before giving up.
if (!runningLock.tryLock(500, TimeUnit.MILLISECONDS)) {
// maybe log a message here?
return;
}
// IMPORTANT: ANY CODE ADDED TO THIS METHOD MUST BE INSIDE THE TRY OR
// YOU RUN THE RISK OF FAILING TO RELEASE THE LOCK!
try {
// perform your job code here...
} finally {
// sb: we're finished; release the lock
runningLock.unlock();
}
}
}
Учитывая, что ваше задание выполняется каждые 30 секунд, нет причин откладывать выполнение одного задания во время выполнения другого — просто отмените его.