Кварц: cron-выражение, которое никогда не будет выполняться



Я знаю, что здесь есть дубликат, который, вероятно, именно мой случай, хотя он заслуживает лучшего объяснения, которое я постараюсь предоставить здесь.



Я работаю с веб-приложением Java, используя контекст приложения Spring. В этом контексте, я определил запланированные задания с помощью кварца. Эти задания запускаются хроном, определенным в a .файл свойств.



весенний контекст встроен в войну, в то время как.файл свойств находится на сервере приложений (Кот в данном конкретном случае).



Это просто прекрасно и позволяет определить различные кроны в зависимости от окружающей среды (разработка, интеграция, производство, ...).



теперь, при запуске этого приложения локально на моем собственном компьютере, я не хочу, чтобы эти задания были выполнены. Есть ли способ написать выражение cron, которое никогда не будет срабатывать?

900   5  

5 ответов:

TL; DR

в Quartz 1, Вы можете использовать этот cron:59 59 23 31 12 ? 2099 (последняя дата).
В Quartz 2 Вы можете использовать этот cron:0 0 0 1 1 ? 2200

используя выражение далеко в будущее

сделал несколько быстрых тестов с помощью org.quartz.CronExpression.

String exp = "0 0 0 1 1 ? 3000";
boolean valid = CronExpression.isValidExpression(exp);
System.out.println(valid);
if (valid) {
    CronExpression cronExpression = new CronExpression(exp);
    System.out.println(cronExpression.getNextValidTimeAfter(new Date()));
}

когда я делаю String exp = "# 0 0 0 1 1 ?"; на isValid возвращает тест false.

С образцом, приведенным выше, выход является следующее:

true
null

значение:

  • выражение является допустимым;
  • нет никакой предстоящей даты, которая соответствует этому выражению.

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

я пробовал несколько лет и выяснил, что раз в год выше 2300, кварц, кажется, больше не беспокоит (хотя я не нашел упоминания о максимальном значении за год в документации Quartz 2). Возможно, есть более чистый способ сделать это, но это удовлетворит мои потребности на данный момент.

Итак, в конце концов, cron я предлагаю 0 0 0 1 1 ? 2200.

Кварц 1 вариант

обратите внимание, что в кварце 1, 2099-последний действительный год. Поэтому вы можете адаптировать выражение cron для использования предложение Мацея Матиса:59 59 23 31 12 ? 2099

альтернатива: использование a дата в прошлом

Arnaud Denoyelle предложил что-то более элегантное, что мой тест выше подтверждает как правильное выражение: вместо того, чтобы выбирать дату в далеком будущем, выберите ее в далеком прошлом:

0 0 0 1 1 ? 1970 (первое допустимое выражение в соответствии с документацией Quartz).

это решение не сработало.

hippofluff подчеркнул, что кварц будет обнаружить выражение в прошлое никогда не будет выполняться и, следовательно, исключение.

org.quartz.SchedulerException: Based on configured schedule, the given trigger will never fire.

это, кажется, было в кварце в течение длительного времени.

извлеченные уроки: тест не является надежным, как это

это подчеркивает слабость моего теста: в случае, если вы хотите проверить CronExpression помните он должен быть nextValidTime1. В противном случае планировщик, которому вы передадите его, просто отклонит его с вышеупомянутым исключение.

я бы посоветовал адаптировать тестовый код следующим образом:

String exp = "0 0 0 1 1 ? 3000";
boolean valid = CronExpression.isValidExpression(exp);
if (valid) {
    CronExpression cronExpression = new CronExpression(exp);
    valid = cronExpression.getNextValidTimeAfter(new Date()) != null;
}
System.out.println("Can I use <" + exp + ">? " + (valid ? "Go ahead!" : "This shall fail."));

там вы идете: не нужно думать, просто читать вывод.


1 это та часть, которую я забыл, когда тестировал решение Арно, делая меня дураком и доказывая, что мой тест не был мной-доказательством.

технически допустимые значения для дополнительного поля Quartz year равны 1970-2099, поэтому 2300 не является ожидаемым значением. Я предполагаю, что вы действительно нужно сделать это, и ваша версия Quartz пытается применить допустимый синтаксис cron (день 1-31, месяц 1-12 и т. д.).

cron: "0 5 31 2 *"

работа терпеливо ждите раннего утра 31 февраля перед запуском. Для эквивалента в кварцевые crontrigger, попробуйте эту строку или какой-то ее вариант:

0 0 5 31 2 ?

попробуйте вот это:59 59 23 31 12 ? 2099

Я нашел это, пытаясь решить аналогичную проблему-отключение выражения cron-но столкнулся с теми же проблемами, требующими действительной даты будущего расписания.

Я также попал проблемы с использованием синтаксиса 7 значений-не могу указать год в расписании cron.

Итак, я использовал это: 0 0 3 ? 2 ПН#5

в следующий раз это будет выполняться:

  1. понедельник, 29 февраля 2044 3:00 утра
  2. Понедельник, 29 Февраля, 2072 3:00 АМ
  3. понедельник, 29 февраля, 2112 3:00 утра
  4. понедельник, 29 февраля, 2140 3:00 утра
  5. понедельник, 29 февраля, 2168 3:00 утра

Так что, по сути, во всех смыслах и целях, он отключен. :)

Ах. Проклятия, это будет работать только для синтаксиса Quartz scheduler-синтаксис Spring CronTrigger не позволяет MON#5 для пятого понедельника

Итак, следующая лучшая вещь-0 0 3 29 2 ? который будет выполняться только в 3 часа ночи 29 февраля (високосные годы)

теперь, при запуске этого приложения локально на моем собственном компьютере, я не хочу, чтобы эти задания были выполнены. Есть ли способ написать выражение cron, которое никогда не будет срабатывать?

если вы хотите отключить планирования на вашем компьютере, у вас есть несколько способов сделать это.

сначала вы можете переместить конфигурацию кварца в @Profileнастройки и включите этот профиль локально. Кварц не начал бы вообще, если профиль не активный.

альтернативой является настройка кварца, чтобы не запускаться автоматически. Там есть SchedulerFactoryBean#setAutoStartup() что вы можете установить в BeanPostProcessor зарегистрирован в профиле разработчика. Хотя этот поток довольно старый, Spring Boot предлагает альтернативу, зарегистрировав SchedulerFactoryBeanCustomizer Боб делать то же самое.

Comments

    Ничего не найдено.