В своей службе событий я пытаюсь удалить задание, но вижу следующее:
NoMethodError: undefined method `jobs' for module Sidekiq::Job
Я знаю, что с помощью ScheduledSet можно удалять, но писать тесты с его помощью я не могу. Услуга:
# frozen_string_literal: true
module Api
module V1
module Events
class Destroy < BaseService
attr_reader :event
def initialize(event:)
@event = event
end
def call
cancel_notification
event.destroy
success!(event)
end
private
def cancel_notification
return if event.notification_job_id.blank? || Sidekiq::Worker.jobs.empty?
Sidekiq::Job.jobs.reject! { |job| job["jid"] == event.notification_job_id }
end
end
end
end
end
Я пытался использовать Sidekiq::Workers, Sidekiq::Worker(alias), но вижу то же самое.
1. Вы проверяете наличие Sidekiq::Worker.jobs, а затем вызываете Sidekiq::Job.jobs? Вы проверили документ на предмет этих проблем? Они вообще доступны? 2. Правильно вы хотите то же самое, что и в stackoverflow.com/questions/48348723/…. 3. Но будьте осторожны: циклическое перебор заданий в очереди никогда не будет хорошей идеей из-за состояния гонки (задание может быть добавлено прямо перед началом цикла). 4. Лучшим подходом является добавление флага к событию (скажем, :cancelled). , и действие API установит для этого флага значение TRUE. Внутри работника проверьте наличие флага и пропустите его соответственно.
Я не уверен, откуда вас упомянули .all
и #reject
на этой съемочной площадке. Похоже, что цель состоит в том, чтобы удалить задание на основе идентификатора.
По сути есть два подхода, первый близок к вашему, найти вакансию по jid и удалить ее (из как удалить вакансию в Sidekiq):
Sidekiq::ScheduledSet.new.find_job([job_id])&.delete
Однако это может работать плохо, когда у вас есть большая очередь событий для обработки, потому что внутри он будет просто повторять все задания (как вы предлагаете), но выше приведен более краткий (более чистый код).
Альтернативным и, на мой взгляд, лучшим подходом может быть добавление атрибута cancelled(_at)
к событию в базе данных (или полное его удаление, как предложил Стефан). Убедитесь, что, когда задание(я) подхватываются работником Sidekiq, вы извлекаете запись и пропускаете дополнительную обработку (это предполагает, что вы запрашиваете базу данных, чтобы получить последнее состояние события в задании). , что является общей практикой и не отправляет в задание все параметры)
Почему бы не передать идентификатор события заданию и не попросить работника получить это событие (возможно, он уже это сделал). Если он не может его найти (поскольку он был уничтожен), рабочему делать нечего. Таким образом, вам не придется возиться с внутренними компонентами Sidekiq.