2012-10-26 6 views
9

Ricordo che non possiamo uccidere il Quartz Job corrente ma possiamo interrompere e fare un controllo booleano ovunque sia necessario se dobbiamo procedere ulteriormente con le operazioni successive o meno.È possibile uccidere un lavoro al quarzo in corso?

Anche quando implementiamo InterruptableJob e chiamiamo lo scheduler.interrupt per interrompere il lavoro, il lavoro attualmente eseguito sarà ancora in esecuzione nel server.

Es:

  1. Una query SQL di nome è stato innescato dal lavoro tramite Hibernate, che richiede molto tempo
  2. Una chiamata è stata fatta a un server di terze parti in cui il server di terze parti richiede molto tempo di rispondere

http://neopatel.blogspot.in/2011/05/quartz-stop-job.html http://forums.terracotta.org/forums/posts/list/3191.page

Qualcuno potrebbe correggere la mia comprensione e spiegarmi come possiamo uccidere o fermare il lavoro "attualmente" in esecuzione?

Grazie, Kathir

risposta

2

Come hai detto, non c'è modo per interrompere "brutalmente" un lavoro in quarzo, né in JAVA.

È possibile incapsulare la logica del lavoro in un thread separato ed eseguirlo con ExecutorService.

Date un'occhiata a questo esempio: https://stackoverflow.com/a/2275596/1517816

supponga tuo QuartzJob è la classe di test e spostare la logica di business nella classe Task.

Speranza che aiuta

+0

Sono d'accordo sul fatto che non possiamo brutalmente uccidere un lavoro in Quarzo né in JAVA. Inoltre, accetta che possiamo ottenere lo stesso tramite ExecutorService. Per mia curiosità, solleva ancora una domanda perché Quartz non ha implementato ExecutorService in modo che possano fornirci un modo per uccidere il lavoro? Oppure c'è un piano futuro nei miglioramenti al quarzo. Grazie per i chiarimenti e per favore fatemi sapere le vostre opinioni. – Kathir

+0

Perché non implementare è probabilmente perché è stato progettato per fornire un'alternativa a questa mancanza nella jvm. Funziona con vecchi jvms e se implementano ExecutorService, il quarzo sarà collegato con un recente progetto jvm e force per migrare – poussma

+0

Probabilmente possono fornire un supporto aggiuntivo o esteso tramite una configurazione. In questo modo possono ottenere la compatibilità verso il basso e il nuovo ... mi manca qualcosa? .. Comunque grazie per il tuo tempo e la spiegazione ... – Kathir

6

è possibile creare nuova classe astratta denominata JobBase per esempio che implementa l'interfaccia IJob e inserire metodo astratto: public abstract void ExecuteJob(IJobExecutionContext context);

Su JobBase è possibile implementa metodo Execute come questo

public abstract class JobBase : IJob,IInterruptableJob 
{ 
    private Thread currentThread; 
    private ILog logger; 
    public JobBase(ILog logger) 
    { 
     this.logger=logger; 
    } 
     public void Execute(IJobExecutionContext context) 
     { 

      var thread = new Thread(()=> 
      { 
       try 
       { 
        this.ExecuteJob(context); 
       } 
       catch(Exception ex) 
       { 
        this.logger.ErrorFormat("Unhandled exception {0}",ex.ToString()); 

       } 
      }); 

      thread.Start(); 
      this.currentThread = thread; 
      this.currentThread.Join(); 
     } 
     public abstract void ExecuteJob(IJobExecutionContext context); 

     public void Interrupt() 
     { 
      currentThread.Abort(); 
     } 
} 

Ogni lavoro imporrà il metodo JobExecute.

public class TestJob :JobBase 
{ 
    private ILog logger; 
    public TeJob(ILog logger):base(logger) 
    { 
    } 

    public override ExecuteJob(IJobExecutionContext context) 
    { 
    } 
} 

dal presupposto che l'uso qualche fabbrica per la creazione di un lavoro

Per Interruzione di un lavoro si chiamare il metodo scheduler.Interrupt(new JobKey(jobName));

+0

Questo sembra esattamente quello di cui ho bisogno. Ma ogni volta che tento di interrompere un lavoro ottengo l'eccezione "ThreadAbortException". – Schoof

+0

@Schoof Questo è corretto. Se dai un'occhiata alla documentazione di 'Thread.Abort()' vedi che genera una 'ThreadAbortException' https://msdn.microsoft.com/en-us/library/system.threading.thread.abort(v = vs.110) .aspx –

0

Non so il motivo per cui nessuno ha menzionato questo, o forse questo non era disponibile al il momento in cui è stata posta la domanda.

C'è un metodo chiamato shutdown per un'istanza Scheduler.

SchedulerFactory factory = new StdSchedulerFactor(); 
Scheduler scheduler = factory.getScheduler(); 

Quanto sopra viene utilizzato per avviare un lavoro come

scheduler.start(); 

Utilizzare una bandierina o qualche cosa di sapere quando interrompere il processo di esecuzione.Quindi utilizzare

scheduler.shutdown(); 

Come ho implementato la mia richiesta:

if(flag==true) 
{ 
    scheduler.start(); 
    scheduler.scheduleJob(jobDetail, simpleTrigger); 
} 
else if(flag==false) 
{ 
    scheduler.shutdown(); 
} 

Dove jobDetail e simpleTrigger sono autoesplicativi.

Spero che aiuti. :)

+2

Questo ucciderà l'intero programmatore invece di un particolare lavoro nello schedulatore – Kathir

+2

Sì, sì sì. Se lo schedulatore ha un solo lavoro. Quindi questo metodo funzionerebbe perfettamente. Ho appena dato un suggerimento. –