Кварцевое повторное задание с экспоненциально увеличивающейся стратегией времени задержки для триггера - PullRequest
0 голосов
/ 16 марта 2019

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

  • Для доставки данных с экспоненциально возрастающей стратегией я создаю работу и для следующих неудачных попыток. (Это спам БД. Кажется, работает, но может быть лучше.)
  • отличается, мое решение состоит в том, чтобы создать повторяемое задание на основе кроны, которое сканирует данные БД и загружает только дату, потому что прошло время (в этом случае мне приходится много работать с Java-частью).

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

Я пытался управлять JobExecutionContext запущенного задания, чтобы использовать тот же JobDetail, регистрируя его в quartzScheduler. Идея состояла в том, чтобы обновить существующую работу с другим триггером. Но проблема в том, что кварц пытается создать новую работу, сохраняя ее в БД.

org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'digex-caas-securepay.b333e5bf-583f-4643-9ad7-ef4b913001f7', because one already exists with this identification.
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1113) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$2.executeVoid(JobStoreSupport.java:1067) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3765) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3763) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:245) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJobAndTrigger(JobStoreSupport.java:1063) ~[quartz-2.3.0.jar:na]
    at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:855) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:249) ~[quartz-2.3.0.jar:na]
    at com.incomm.ecomm.services.quartz.OrderQuartzJobScheduler.registerSecurePayPostServiceJob(OrderQuartzJobScheduler.java:59) ~[classes/:na]

Вопросы (пожалуйста, ответьте на любой):

  • Как управлять с помощью обновлений триггера кварцевого задания (если оно не было обработано успешно - триггер обновления с другим временем срабатывания)?
  • Как управлять с помощью обновлений задания кварца (если оно не было обработано успешно - обновите задание с новым триггером)?
  • Как зарегистрировать экспоненциально увеличивающуюся стратегию времени задержки для триггера?

Ответы [ 2 ]

1 голос
/ 17 марта 2019

Простой ответ:

scheduler.rescheduleJob(trigger.getKey(), trigger);

Подробный ответ:

  • Как управлять с помощью обновлений триггера кварцевых заданий

scheduler.rescheduleJob (trigger.getKey (), trigger);

  • Как управлять с помощью обновлений заданий кварца

Это не важнобольше, если триггер обновлен.

  • Как зарегистрировать экспоненциально увеличивающуюся стратегию времени задержки для триггера?

один триггер может быть перенесен на любой другойвремя.Время для следующего выполнения может быть рассчитано с использованием любой реализации IntervalCalculationStrategy.

Пример переназначения задания:

Задание и сведения о задании можно взять из JobExecutionContext, но не обязательно.Триггер может быть подключен только к одному заданию, поэтому он достаточно хорош для обновления кварца triggerKey:

@Autowired
private Scheduler scheduler;
@Autowired
private IntervalCalculationStrategy intervalCalculation;

public <T extends QuartzJobBean> void registerSecurePayPostServiceJob(
    JobExecutionContext firedJobExecutionContext) {
  Optional<SimpleTriggerImpl> mutableTrigger =
      ofNullable(firedJobExecutionContext)
          .map(JobExecutionContext::getTrigger)
          .filter(SimpleTriggerImpl.class::isInstance)
          .map(SimpleTriggerImpl.class::cast);
  try {
    if (mutableTrigger.isPresent()) {
      SimpleTriggerImpl trigger = mutableTrigger.get();
      int nextAttemptNumber = trigger.getTimesTriggered();
      log.trace("trigger: {} fired [{}] times", trigger.getFullName(),
          trigger.getTimesTriggered());
      trigger.setStartTime(intervalCalculation.calculateNextTryDate(nextAttemptNumber));
      this.scheduler.rescheduleJob(trigger.getKey(), trigger);
    }
  } catch (SchedulerException e) {
    log.error("job was not rescheduled <{}>", firedJobExecutionContext.getJobDetail(), e);
  }
}
1 голос
/ 16 марта 2019
  • Вы можете следовать этому подходу (механизм повтора и может не иметь повторные попытки разрешены) ref: Кварцевая повторная попытка при отказе
  • Для каждого сбоя вы можете обновить счетчик и отправить электронное письмо. Так что вы будет знать в макс попытаться также успешно прошло или нет.
  • Если не позже, у вас будет панель для просмотра неисправных (включает не раз его пытался) и может запустить его вручную механизм.
  • Вместо e.setRefire, сразу вы можете установить временную шкалу ex. Спустя 120 минут запланируйте его запуск, т.е. на основе механизма JobDataMap
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...