2017-02-01 2 views
0

Я использую resque на Heroku, который время от времени прерывает ваши задания с помощью SIGTERM.Как обращаться с SIGTERM с resque-статусом в сложных заданиях

До сих пор я перевалено это с простой:

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

Мы начали использовать Resque-статус, чтобы мы могли следить за работу, но выше метод явно нарушает, что как работа будет шоу завершено, когда на самом деле оно отложено на другую работу.

Мое настоящее мышление заключается в том, что вместо того, чтобы откладывать текущее задание в режиме resque, должно быть другое задание, которое перезагружает задания, которые потерпели неудачу из-за SIGTERM.

Хитрость приходит в том, что некоторые рабочие места являются более сложными:

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

Простое удаление спасение и просто Повторная попытка эти рабочие места будут вызывать исключение, когда do_part1 получает повторяется.

ответ

0

Глядя более глубоко в то, как работает статус resque, возможная работа заключается в том, чтобы перейти непосредственно к повторной очереди, используя те же параметры, что и режим resque-status.

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 

Конечно, это не документирован так может быть несовместимо с будущими выпусками Resque-статуса.

Существует обратная связь: между этой неудачей работы и новым заданием, забирающим ее, статус первого задания будет сообщаться по статусу resque. Вот почему я повторно поднимаю новое исключение - иначе статус задания будет отображаться до тех пор, пока новый рабочий не заберет старую работу, которая может запутать процессы, которые смотрят и ждут завершения задания.

Подняв новое исключение DeferredToNewJob, статус задания временно покажет неудачу, с которой легче работать в интерфейсе, и конкретное исключение может быть автоматически очищено от очереди сбоев resque.

UPDATE

спасательное-статус обеспечивает поддержку on_failure обработчика. Если метод с таким именем определяется как метод экземпляра класса, мы можем сделать это еще проще

Вот мой on_failure

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

При этом в месте работы не проводит в основном нет времени в неисправном состоянии для процессов, наблюдающих за его статусом. Кроме того, если resque-status находит этот обработчик, то он не будет создавать исключение до resque, поэтому он не будет добавлен в неудачную очередь.