Отмена запланированной работы Sidekiq в Rails
Для некоторых заданий Sidekiq в моем приложении запланировано изменение состояния ресурса на cancelled
если пользователь не отвечает в течение определенного периода времени. Существует много информации о том, как лучше всего выполнить эту задачу, но на самом деле ни одна из них не отменяет работу.
Чтобы отменить работу, код в вики говорит:
class MyWorker
include Sidekiq::Worker
def perform(thing_id)
return if cancelled?
thing = Thing.find thing_id
thing.renege!
end
def cancelled?
Sidekiq.redis {|c| c.exists("cancelled-#{jid}") }
end
def self.cancel!(jid)
Sidekiq.redis {|c| c.setex("cancelled-#{jid}", 86400, 1) }
end
end
Тем не менее здесь предлагается, чтобы я сделал что-то вроде
def perform(thing_id)
thing = Thing.find thing_id
while !cancel?(thing)
thing.ignore!
end
end
def cancel?(thing_id)
thing = Thing.find thing_id
thing.matched? || thing.passed?
end
Что сбивает с толку этот и подобный код в вики, так это то, что он не отменяет работу. Приведенный выше пример просто выполняет обновление thing
если cancelled?
возвращается false
(как и должно быть), но не отменяется, если и когда он вернет true в будущем. Это просто терпит неудачу с сообщением об ошибке перехода AASM и отправляется RetrySet. призвание MyWorker.cancel! jid
в коде модели выдает неопределенную переменную ошибку. Как я могу получить доступ к этому jid в модели? Как на самом деле можно отменить или удалить эту конкретную работу? Спасибо!
3 ответа
Хорошо, так получается, у меня уже был один вопрос. Один из наборов кода, который я включил, был функционально похожей версией кода из вики. Решение другого вопроса ("как я могу получить доступ к этому jid в модели?") Кажется действительно очевидным, если вы еще не знакомы с программированием, но в основном: сохраните jid в столбце базы данных, а затем извлекайте / обновляйте его всякий раз, когда это нужно! Duh!
# The wiki code
class MyWorker
include Sidekiq::Worker
def perform(thing_id)
return if cancelled?
# do actual work
end
def cancelled?
Sidekiq.redis {|c| c.exists("cancelled-#{jid}") }
end
def self.cancel!(jid)
Sidekiq.redis {|c| c.setex("cancelled-#{jid}", 86400, 1) }
end
end
# create job
jid = MyWorker.perform_async("foo")
# cancel job
MyWorker.cancel!(jid)
Вы можете сделать это, но это не будет эффективным. Это линейное сканирование для поиска запланированной работы по JID.
require 'sidekiq / api' Sidekiq:: ScheduledSet.new.find_job (jid).try (: delete) В качестве альтернативы ваша работа может посмотреть, насколько она все еще актуальна при запуске.