2017-02-01 1 views
0

Ich habe Resque auf Heroku verwendet, die von Zeit zu Zeit Ihre Jobs mit einem SIGTERM unterbrechen wird.Wie man SIGTERM mit resque-status in komplexen Jobs behandelt

Bisher habe ich dies mit einem einfachen Handhabung:

def process(options) 
    do_the_job 
rescue Resque::TermException 
    self.defer options 
end 

Wir begonnen haben resque-Status mit, so dass wir den Überblick über Arbeitsplätze halten, aber die Methode oben offensichtlich bricht, dass als der Job Show abgeschlossen, wenn es tatsächlich auf einen anderen Job verschoben wurde.

Mein derzeitiges Denken ist, dass, anstatt den aktuellen Job in resque zu verzögern, es einen anderen Job geben muss, der Jobs neu einreiht, die aufgrund von SIGTERM fehlgeschlagen sind.

Der Trick kommt, dass einige Arbeitsplätze sind komplizierter:

def process(options) 
    do_part1 unless options['part1_finished'] 
    options['part1_finished'] 
    do_part2 
rescue Resque::TermException 
    self.defer options 
end 

einfach die Rettung zu entfernen und einfach erneut versuchen diese Arbeitsplätze würden eine Ausnahme verursachen, wenn do_part1 wiederholt wird.

Antwort

0

Wenn Sie tiefer in die Funktionsweise von resque-status einsteigen, besteht eine mögliche Umgehung darin, direkt zu resque für die re-queue zu wechseln, wobei dieselben Parameter wie beim resque-status verwendet werden.

def process 
    do_part1 unless options['part1_finished'] 
    options['part1_finished'] 
    do_part2 
rescue Resque::TermException 
    Resque.enqueue self.class, uuid, options 
    raise DeferredToNewJob 
end 

Natürlich ist dies undokumentiert, daher möglicherweise nicht kompatibel mit zukünftigen Versionen von resque-Status.

Es gibt einen Nachteil: zwischen dem Scheitern des Jobs und dem Abholen des neuen Jobs wird der Status des ersten Jobs durch den Resque-Status gemeldet. Das ist der Grund, warum ich eine neue Ausnahme erneut erstelle - andernfalls wird der Jobstatus als abgeschlossen angezeigt, bis der neue Mitarbeiter den alten Job annimmt. Dies kann Prozesse verwirren, die den Job überwachen und warten.

Durch das Auslösen einer neuen Ausnahme DeferredToNewJob zeigt der Auftragsstatus vorübergehend einen Fehler an, was am Frontend leichter zu umgehen ist, und die bestimmte Ausnahme kann automatisch aus der Fehlerwarteschlange gelöscht werden.

UPDATE

resque-Status sieht on_failure Handler-Support. Wenn eine Methode mit diesem Namen als Instanz Methode für die Klasse definiert ist, können wir dies machen noch einfacher

Hier mein ON_FAILURE ist

def on_failure(e) 
    if e.is_a? DeferredToNewJob 
    tick('Waiting for new job') 
    else 
    raise e 
    end 
end 

In diesem Ort die Arbeit verbringt im Grunde keine Zeit im gescheiterten Staat für Prozesse, die ihren Status überwachen. Wenn resque-status diesen Handler findet, löst er die Ausnahme nicht aus, so dass er nicht zur fehlgeschlagenen Warteschlange hinzugefügt wird.

Verwandte Themen