Политика осечки кварца

Я новичок в Quartz в Java, и у меня есть вопрос о пропуске зажигания. Я установил SimpleTrigger, который срабатывает каждые 5 секунд. Иногда связанная работа занимает более 5 секунд. Я хотел бы пропустить задание, когда это произойдет (установленный интервал был достигнут триггером). Проходя через API, я не нашел политику осечки, которая могла бы это сделать. Какие-нибудь хитрости? Спасибо вам за помощь


person El vengador de la capa    schedule 13.04.2011    source источник


Ответы (1)


Есть несколько различных политик осечки, которые могут вам помочь. Посмотрите javadocs здесь: http://www.quartz-scheduler.org/docs/api/1.8.0/org/quartz/SimpleTrigger.html обращая внимание на статические конечные константы, начинающиеся с MISFIRE_INSTRUCTION_RESCHEDULE_*. Существует ряд различных вариантов поведения в отношении подсчета повторов, но я думаю, что они выполнят то, что вы пытаетесь сделать.

person stevevls    schedule 13.04.2011
comment
Ни одна из опций MISFIRE_INSTRUCTION_RESCHEDULE_*, по-видимому, не указывает отменить (или просто пропустить) текущую длительную работу и запустить следующую. Это приводит к тому, что следующее задание задерживается ровно на время задержки длинного задания. - person El vengador de la capa; 14.04.2011
comment
Ах... не было ясно, что вы хотели отменить долгоиграющую работу. В этом случае такой функционал не предоставляется. Quartz не был написан с учетом такого варианта использования, поэтому вам придется поработать над ним. Во-первых, ваше задание должно быть экземпляром InterruptableJob: quartz-scheduler.org/docs/api/1.8.1/org/quartz/. Затем вам понадобится другое задание или поток, периодически использующий Scheduler API, чтобы прервать исходное задание. Или... вы можете написать свой собственный демон (что может быть проще). В любом случае, убедитесь, что вашу работу можно прервать! - person stevevls; 14.04.2011
comment
Это хорошая идея. Спасибо. Тем не менее, используя Quartz, как справиться с ситуацией, когда задание (которое обычно занимает меньше времени, установленного для триггера) занимает больше времени, чем время, установленное для триггера. Вы должны просто отложить весь график или даже навсегда заморозить весь график? Я думаю, это может быть довольно распространенной ситуацией, верно? - person El vengador de la capa; 14.04.2011
comment
Это определенно происходит! Если ваша работа не должна выполняться в режиме реального времени, вполне нормально время от времени пропускать выполнение и позволить ему наверстать упущенное в следующий раз. Например. если вы обрабатываете строки БД за последние пять секунд, измените код, чтобы он обращался к строкам, которые изменились с момента последнего запуска (отслеживание метки времени с помощью JobExecutionContext). Конечно, эта стратегия зависит от того, что ожидаемое время выполнения меньше, чем интервал расписания, как вы говорите... иначе все будет накапливаться! Кроме того, поскольку планировщик является многопоточным, это задание не будет препятствовать запуску других заданий. - person stevevls; 14.04.2011
comment
Хотя в режиме реального времени было бы оптимально, этого просто не произойдет. Так что я был бы в порядке, пропустив одну казнь здесь и там. Я не уверен, что смогу сделать то, что вы предлагаете. Моя проблема в том, что иногда после запуска метода Job execute() (который содержит код, выполняющий задание) у меня нет возможности взаимодействовать с расписанием (возможно, я ошибаюсь). Так что, если этот код будет выполняться целую вечность, я ничего не смогу сделать, чтобы остановить его и перейти к следующему. Так ли это? - person El vengador de la capa; 14.04.2011
comment
Если ваше задание является экземпляром InterruptableJob, вы можете отменить его после запуска с помощью метода прерывания планировщика. Дело в том, что вам понадобится какой-то сторожевой поток или другая работа для отмены. Но это начинает раздражать... Я бы сказал, что вам лучше убедиться, что ваша работа не может длиться слишком долго. В любом случае, трудно дать слишком много советов, не вдаваясь в подробности того, что именно вы пытаетесь сделать! - person stevevls; 16.04.2011
comment
Нет проблем с созданием моего задания и экземпляра InterruptableJob. Я также согласен с тем, что нить, которая наблюдает за работой, - это не выход. Чего я не понимаю (опять же я новичок в Quartz), так это почему планировщик не ведет внутренние часы, которые следят за ходом выполнения задания и дают вам контроль (через Листнера?) для вмешательства. Так ли это? На самом деле не имеет значения, что это за работа (в моем случае вычисление некоторых данных, которое обычно занимает менее 2 секунд, но в некоторых случаях может занять вечность ... не предсказуемо, просто природа зверя). - person El vengador de la capa; 16.04.2011
comment
Хм... вы можете попробовать реализовать TriggerListener и отменить свою работу (если она запущена) в случае осечки. Вы потеряете 5 секунд (или любой другой интервал) полезного вычислительного времени, но, возможно, это может сработать в вашем случае неконтролируемого задания. - person stevevls; 16.04.2011
comment
Я изучил это и не думаю, что есть способ реализовать тайм-ауты только с помощью Quartz. На прошлой неделе я попробовал идею TriggerListener... она не очень хорошо работает. В конце концов я реализовал монитор заданий (идея, которую мы обсуждали ранее), который начинает наблюдение с помощью JobListener. Работает отлично (пока). Тем не менее, мне кажется, это должно быть частью Quartz. - person El vengador de la capa; 18.04.2011