Quartz.NET: нужен CronTrigger для экземпляра iStatefulJob, чтобы * задерживать, а не пропускать *, если работа выполняется в то время, когда срок выполнения расписания - PullRequest
0 голосов
/ 20 декабря 2010

Приветствую, ваш дружелюбный квартал Quartz.NET n00b вернулся!

У меня есть служба Windows, на которой выполняются экземпляры iStatefulJob по схеме расписаний на основе Quartz.NET CronTrigger ... Строка CRON, используемая для планирования задания: "0 0/1 * * *? *"

Все отлично работает. Однако, если у меня есть задание, которое должно запускаться, скажем, по метке X: 00 каждой минуты, и это задание выполняется более минуты, я замечаю, что последующее задание запускается НЕМЕДЛЕННО после завершения задания выполнение, а не ожидание следующего запланированного запуска, эффективно «ставит в очередь» вместо простого пропуска задания до следующего запланированного запуска.

Я включил триггер CronTrigger MisfireInstruction DONOTHING, но то же самое происходит, когда задание выходит за пределы следующего запланированного графика выполнения.

Как получить экземпляр iStatefulJob, чтобы просто пропустить триггер запланированного выполнения, если он в данный момент работает, вместо того, чтобы задерживать его до завершения первого выполнения?

Я явно установил триггер. MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;

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

  • Задание выполняется в 9:00:00, заканчивается в 9:01:30 <- задание выполняется в 1: 30 </li>
  • Задание выполняется в 9:01:30, заканчивается в 9:03:00 <- последующее задание, которое должно было выполняться в 9: 01: 00 </li>
  • Работа выполняется в 9:04:00, заканчивается в 9:05:30 <- разве эта не должна была выполняться в 9: 03: 00? </li>
  • Задание выполняется в 9:05:30, заканчивается в 9:07:00 <- последующее задание, которое должно было быть выполнено в 9: 05: 00 </li>
  • Работа выполняется в 9:08:00, заканчивается в 9:09:30 <- разве это не должно было выполняться в 9: 07: 00? </li>

... кажется, что он работает правильно в первый раз, в минуту ... задерживается на 30 секунд по истечении 90-секундного времени выполнения задания, а затем, вместо ожидания до СЛЕДУЮЩЕЙ полной минуты, ВЫПОЛНЯЕТ НЕМЕДЛЕННО в 30-секундная отметка ... Вдвойне странно, что она затем завершает ВТОРОЕ задание на минутной отметке, но ждет, пока не выполнится СЛЕДУЮЩАЯ минутная отметка, вместо запуска назад-2-назад ...

Похоже, что он работает правильно КАЖДЫЙ ДРУГОЙ ЗАПУСК, когда он не работает: 30 баллов ...

Каков наилучший способ получить работу не для того, чтобы задерживать / ставить в очередь, а просто пропустить, пока она не простаивает и не наступит следующий график?

РЕДАКТИРОВАТЬ: я попытался вернуться к iJobs вместо iStatefulJobs, используя ту же инструкцию пропуска триггера DONOTHING, но задание выполняется КАЖДУЮ МИНУТУ, несмотря на то, что предыдущее выполнение было все еще активным. Я не могу заставить его пропустить запланированный запуск, если он в данный момент выполняется с iJob или iStatefulJob ...

РЕДАКТИРОВАТЬ # 2: Я думаю, что мои триггеры НИКОГДА не дают сбои, поэтому DoNothing как инструкция пропуска зажигания бесполезен ... Учитывая это, я думаю, мне нужен другой механизм, чтобы определить, является ли экземпляр задания расписания выполняется, чтобы гарантировать, что задание пропускает свое следующее выполнение до следующего запланированного времени, а не откладывает его до завершения первого экземпляра ...

EDIT3: я попытался добавить элемент в карту данных задания iStatefulJob с именем «IsRunning» ... Я установил для него значение ИСТИНА при запуске последовательности выполнения, а затем вернул его в значение false после завершения задания. Перед выполнением он проверяет элемент, который, по-видимому, сохраняется между заданиями, и преждевременно завершает выполнение (регистрируя «JOB SKIPPED!»), Если он обнаруживает, что это правда ... Это, к сожалению, не работает, возможно, по очевидным причинам: Если задания выполняются в соответствии с расписанием, указанным выше, то задание никогда не выполняется одновременно с самим собой, поскольку оно задерживает запуск до завершения задания, поэтому эта проверка бесполезна. Согласно документации, возврат к iJob из iStatefulJob здесь не поможет, поскольку карта данных заданий сохраняется только между заданиями с типом задания с сохранением состояния ...

Я до сих пор не решил, как пропустить запланированное задание вместо того, чтобы откладывать его до завершения текущей итерации ... Если у кого-то есть идеи, вы спасатель! :)

1 Ответ

2 голосов
/ 17 июня 2011

Это должно быть вызвано пропуском Предела RAMJobStore (http://quartznet.sourceforge.net/apidoc/topic2722.html).

Промежуток времени, в течение которого триггер должен пропустили его в следующий раз, в порядок рассмотрения "осечка" и, таким образом, его осечка инструкция применяется.

Это 60 секунд по умолчанию. Таким образом, задание не считается «пропущенным» до тех пор, пока оно не опоздает более чем на значение misfiredThreshold.

Чтобы решить проблему, просто уменьшите этот порог (для кодов ниже 1 мс):

...   
properties["quartz.jobStore.misfireThreshold"] = "1";
...
schedulerFactory = new StdSchedulerFactory(properties);

Это должно решить проблему.

...