2015-05-20 19 views
8

Sto costruendo un servizio Windows che sta eseguendo un'operazione pianificata che elabora una coda di comandi (da un sistema legacy) a intervalli regolari (una volta al minuto) usando Quartz.netConsentire a Quartz.net di ignorare i fallimenti

Se l'operazione richiede più di 1 minuto, il che sarebbe inusuale ma possibile in determinate circostanze, mi piacerebbe che ignorasse semplicemente i trigger che non avevano sparato.

Tuttavia, non riesco a farlo accadere. Esegue l'elaborazione e quindi attiva rapidamente tutti i trigger che ha perso in rapida successione. Come ho capito, puoi impostare una soglia per i fallimenti, ma non mi sembra di essere in grado di farlo funzionare.

Sto utilizzando [DisallowConcurrentExecution()] sul processo per garantire che sia in esecuzione una sola istanza del processo in qualsiasi momento.

Di seguito sono riportati alcuni frammenti. Prima passaggio in alcune informazioni di configurazione: è così che si imposta la soglia di mancato spegnimento?

NameValueCollection config = new NameValueCollection(); 
    config.Add("quartz.jobStore.misfireThreshold", "600000"); 

    schedFact = new StdSchedulerFactory(config); 

Costruire un grilletto con quello che presumo di essere l'impostazione corretta di ignorare fa cilecca:

var trigger = TriggerBuilder.Create() 
        .WithIdentity("trigger1", "group1") 
        .StartNow() 
        .WithSimpleSchedule( x => x.WithMisfireHandlingInstructionIgnoreMisfires() 
        .WithIntervalInSeconds(60) 
        .RepeatForever()) 
        .Build(); 

Pensieri molto apprezzato.

Codice per il lavoro: Basta giocare con idee approssimative a questo punto, quindi è sufficiente eseguire un'app per console e ritardare in modo casuale un lavoro in modo che scatti sopra l'intervallo impostato su 10 secondi. Tutti i backup incendiati si accendono in rapida successione dopo un paio di ritardi.

[DisallowConcurrentExecution()] 
public class SomeJob : IJob 
{ 
    public SomeJob() { } 
    public void Execute(IJobExecutionContext context) 
    { 
     Random rnd = new Random(DateTime.UtcNow.Second); 
     int delay = rnd.Next(2); 
     Console.WriteLine("Executing Job with delay of "+ delay + " at " + DateTime.UtcNow.ToString()); 

     if (delay == 1) 
     { 
      System.Threading.Thread.Sleep(1000 * 25); // sleep for 25 seconds 
     } 
    } 
} 





Example console output: 
Executing Job with delay of 1 at 21/05/2015 21:27:17 
Executing Job with delay of 1 at 21/05/2015 21:27:42 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- stacked misfires 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- 
Executing Job with delay of 0 at 21/05/2015 21:28:16 
Executing Job with delay of 0 at 21/05/2015 21:28:26 
Executing Job with delay of 1 at 21/05/2015 21:28:36 
Executing Job with delay of 0 at 21/05/2015 21:29:01 
Executing Job with delay of 0 at 21/05/2015 21:29:01 
Executing Job with delay of 1 at 21/05/2015 21:29:06 
+0

Potresti incollare il codice per il tuo lavoro? – LeftyX

+0

Grazie per la ricerca: ho aggiornato il post originale con il codice del lavoro. –

+0

Domanda stupida: come può sparare il tuo lavoro ogni 30 secondi quando il tuo grilletto viene attivato ogni minuto? – LeftyX

risposta

13

WithMisfireHandlingInstructionIgnoreMisfires() è il metodo sbagliato per ciò che si vuole, non significa che il lavoro non si innescherà perde colpi, significa che scatterà tutti i trigger che sono stati mancati nel più breve tempo possibile e poi tornare al normale programma. Questo è ciò che vedi accadere.

Quello che ti serve è WithMisfireHandlingInstructionNextWithRemainingCount(). Questo segnalerà allo schedulatore di ignorare i fallimenti e attendere il prossimo orario pianificato. Le strategie soddisfacenti possono essere un po 'confuse, per una spiegazione concisa guarda here (è per lo schedulatore Java ma non importa).

Anche con la giusta strategia, è necessario capire come funziona la soglia di mancato spegnimento, se si sbaglia, il grilletto potrebbe sparare.

Dalla documentazione: "Una mancata accensione è il lasso di tempo entro il quale un trigger deve aver perso il suo tempo di spegnimento successivo, in modo che possa essere considerato" misfired "e quindi avere applicata la sua accensione irregolare".

Hai impostato il valore per 600000 millisecondi (e questo valore è per tutti i trigger, purtroppo non esiste una soglia al di trigger) - la strategia di mancata accensione sarà applicata solo se i fuochi di innesco 600000 millisecondi dopo il tempo avrebbe dovuto essere licenziato. È possibile abbassarlo o aumentarlo in base alle proprie esigenze.

Per ulteriori informazioni sulla soglia di mancato accensione, leggere here.

+0

Brillante grazie, buon collegamento. Passare a WithMisfireHandlingInstructionNextWithRemainingCount e impostare la soglia di mancato spegnimento a metà dell'intervallo sembra fare il lavoro alla grande. –

+0

@AssolutamenteN contento che abbia funzionato, ricordati di upvote pure –

+0

Lo farò non appena avrò più di 15 reputazione ... –