Pregunta sobre triggers, quartz.net – Refire el activador de quartz.net después de 15 minutos si el trabajo falla con una excepción

13

He buscado una respuesta sobre cómo reactivar un trabajo después de un período de tiempo determinado, si el trabajo arroja una excepción. No puedo ver ninguna forma simple de hacer esto.

si configuro mi gatillo de esta manera:

JobDetail job = new JobDetail("Download catalog", null, typeof(MyJob));
job .Durable = true;
Trigger trigger= TriggerUtils.MakeDailyTrigger(12, 0);
trigger.StartTimeUtc = DateTime.UtcNow;
trigger.Name = "trigger name";
scheduler.ScheduleJob(job , trigger);

Y MyJob se parece a esto:

public class MyJob : IJob
{
    public void Execute(JobExecutionContext context)
    {
        var service = new service();


        try
        {
            service.Download();
        }
        catch (Exception)
        {
            throw;
        }

    }
}

¿Cómo hago que el desencadenante vuelva a encenderse / volver a activarse después de 15 minutos si la llamada service.Download () lanza algún tipo de excepción?

Tu respuesta

4   la respuesta
0
// don't forget to use @PersistJobDataAfterExecution without it, the jobExecutionContext will reset the value of count.     

SimpleTriggerImpl retryTrigger = new SimpleTriggerImpl();
    retryTrigger.setName("jobname");
    retryTrigger.setRepeatCount(0);
    retryTrigger.setJobKey(jobExecutionContext.getJobDetail().getKey());
    final Calendar cal = getCalendarInstance();
    cal.add(Calendar.MINUTE, 1); //retry after one minute
    retryTrigger.setStartTime(cal.getTime());
    try {
        jobExecutionContext.getScheduler().scheduleJob(retryTrigger);   // schedule the trigger
    } catch (SchedulerException ex) {
        logger.error("something went wrong", ex); 
    }
    JobExecutionException e2 = new JobExecutionException("retrying...");
    e2.refireImmediately();
    throw e2;
6

artz.net que se retire de inmediato:

public class MyJob : IJob
{
    public void Execute(JobExecutionContext context)
    {
        var service = new service();

        try
        {
            service.Download();
        }
        catch (Exception ex)
        {
              JobExecutionException qe = new JobExecutionException(ex);
              qe.RefireImmediately = true;  // this job will refire immediately
              throw qe;  
        }
    }
}

Puedes encontrar alguna informaciónaquí yaquí.

ACTUALIZAR:

Hice algunas pruebas y parece que puede programar un nuevo activador dentro de un trabajo en ejecución.
Puedes probar algo como esto:

public class MyJob : IJob
{
    public void Execute(JobExecutionContext context)
    {
        var service = new service();

        try
        {
            service.Download();
        }
        catch (Exception ex)
        {
            JobExecutionException qe = new JobExecutionException(ex);
            // qe.RefireImmediately = true;  // this job will refire immediately
            // throw qe;  
            OnErrorScheduleJob(context);

        }
    }

    private void OnErrorScheduleJob(JobExecutionContext context)
    {
        var jobOnError = context.Scheduler.GetJobDetail("ONERRORJOB", "ERROR");
        if (jobOnError == null)
        {
        JobDetail job = new JobDetail("ONERRORJOB", "ERROR", typeof(MyJob));
        job.Durable = false;
        job.Volatile = false;
        job.RequestsRecovery = false;

        SimpleTrigger trigger = new SimpleTrigger("ONERRORTRIGGER",
                        "ERROR",
                        DateTime.UtcNow.AddMinutes(15),
                        null,
                        1,
                        TimeSpan.FromMinutes(100));

        context.Scheduler.ScheduleJob(job, trigger);     
        }
    }
}
@mslot: He actualizado mi respuesta. LeftyX
Sí. Esto lo he leído, pero no es una buena solución, ya que podría significar que se produciría muchos miles de veces (o incluso millones de veces). Pero es bueno ver que has llegado a esta conclusión. mslot
@mslot: no hay problema. Me alegro de haberte ayudado. LeftyX
Gracias: D Tuve la misma idea, pero esta es la primera vez que uso cuarzo, así que no estaba seguro de que pudieras usar el contexto. mslot
8

tar un trabajo como se describe aquí:http://thecodesaysitall.blogspot.cz/2012/03/quartz-candy-part-1.html.

En esta solución se separa la lógica de reintento del trabajo en sí mismo, por lo que se puede reutilizar

Si implementa la lógica de reintento en el trabajo como se sugiere en otras respuestas aquí, debe implementarse nuevamente en cada trabajo.

Edición: Según la nota de Ramanpreet Singh, se puede encontrar una mejor soluciónaquí: https://blog.harveydelaney.com/quartz-job-exception-retrying/

La solución enlazada fue mejorada aquí:blog.harveydelaney.com/quartz-job-exception-retrying Ramanpreet Singh
Estoy de acuerdo. La respuesta aceptada es una solución de "correas y llaves" (que está bien si solo necesita hacer el trabajo), pero agregar un "escucha de reintentos" podría ser una solución mejor (y más reutilizable) a largo plazo. No creo que la implementación sea perfecta, pero es un buen lugar para comenzar ... Fuente en GitHub:github.com/malmgren80/Quartz.Candy David Kirkland
19

no es necesario crear una nueva JobDetail como la descrita por LeftyX. Solo puede programar un nuevo activador que esté conectado a JobDetail desde el contexto actual.

public void Execute(JobExecutionContext context) {
    try {
        // code
    } catch (Exception ex) {
        SimpleTriggerImpl retryTrigger = new SimpleTriggerImpl(Guid.NewGuid().ToString());      
        retryTrigger.Description = "RetryTrigger";
        retryTrigger.RepeatCount = 0;
        retryTrigger.JobKey = context.JobDetail.Key;   // connect trigger with current job      
        retryTrigger.StartTimeUtc = DateBuilder.NextGivenSecondDate(DateTime.Now, 30);  // Execute after 30 seconds from now
        context.Scheduler.ScheduleJob(retryTrigger);   // schedule the trigger

        JobExecutionException jex = new JobExecutionException(ex, false);
        throw jex;
    }
}

Esto es menos propenso a errores que la creación de un nuevo JobDetail. Espero que ayude.

Preguntas relacionadas