Pergunta sobre quartz.net, triggers – Refira o gatilho do quartz.net após 15 minutos se o trabalho falhar com exceção

13

Procurei uma resposta sobre como reativar um trabalho depois de um tempo, se o trabalho gerar uma exceção. Eu não consigo ver nenhuma maneira simples de fazer isso.

se eu definir meu gatilho assim:

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);

E o MyJob fica assim:

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


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

    }
}

Como eu faço o gatilho para refinar / religar depois de 15 minutos se a chamada service.Download () lança algum tipo de exceção?

Sua resposta

4   a resposta
8

Eu acho que a resposta certa é usar JobListener para tentar novamente um trabalho como descrito aqui:http://thecodesaysitall.blogspot.cz/2012/03/quartz-candy-part-1.html.

Você separa a lógica de nova tentativa do próprio Job nesta solução, para que possa ser reutilizada.

Se você implementar a lógica de repetição na tarefa, conforme sugerido em outras respostas, ela deverá ser implementada novamente em cada tarefa.

Edit: De acordo com a nota Ramanpreet Singh melhor solução pode ser encontradaAqui: https://blog.harveydelaney.com/quartz-job-exception-retrying/

A solução vinculada foi melhorada aqui:blog.harveydelaney.com/quartz-job-exception-retrying Ramanpreet Singh
Concordo. A resposta aceita é uma solução de "cintos e chaves" (o que é bom se você só precisa fazer o trabalho), mas adicionar um "ouvinte de repetição" pode ser uma solução de longo prazo melhor (e mais reutilizável). Eu não acho que a implementação é perfeita, mas é bom lugar para começar ... Fonte no GitHub:github.com/malmgren80/Quartz.Candy David Kirkland
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;
19

Na verdade, não é necessário criar um novo JobDetail como descrito por LeftyX. Você pode apenas agendar um novo gatilho conectado ao JobDetail a partir do contexto atual.

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;
    }
}

Isso é menos propenso a erros do que criar um novo JobDetail. Espero que ajude.

6

Eu acho que a única opção que você tem é capturar o erro e dizer ao Quartz.net para refinar imediatamente:

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;  
        }
    }
}

Você pode encontrar algumas informaçõesAqui eAqui.

ATUALIZAR:

Eu fiz alguns testes e parece que você pode agendar um novo gatilho dentro de um trabalho em execução.
Você pode tentar algo assim:

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);     
        }
    }
}
Obrigado: D Eu tive a mesma idéia, mas esta é a primeira vez que uso o quartzo, então eu não tinha certeza se você poderia usar o contexto. mslot
Sim. Isso eu li, mas não é uma boa solução, porque poderia significar que iria se recusar muitas vezes (ou mesmo se refazer milhões de vezes). Mas é bom ver que você chegou a essa conclusão. mslot
@mslot: atualizei minha resposta. LeftyX
@mslot: não há problema. Ainda bem que ajudei. LeftyX

Perguntas relacionadas