Search code examples
ruby-on-railsrubyredisjobssidekiq

NoMethodError: undefined method `jobs' for module Sidekiq::Job


In my event service I'm trying to delete a job, but I see this:

NoMethodError: undefined method `jobs' for module Sidekiq::Job

I know that it is possible to delete using ScheduledSet, but I cannot write tests using it. Service:

# 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

I tried to use Sidekiq::Workers, Sidekiq::Worker(alias) but see the same thing


Solution

  • I'm not sure where you got mentioned .all and #reject on that set from. It seems that the intent is to remove a job based on the id.

    There are basically two approaches, first closes to your approach, find the job based on the jid and remove it (from how to delete a job in sidekiq):

    Sidekiq::ScheduledSet.new.find_job([job_id])&.delete
    

    This however may perform badly when you have a large queue of events to process, because internally it will just iterate all jobs (like you're suggesting), but above is more concise (cleaner code).

    An alternative, and imho better, approach may be to add a cancelled(_at) attribute to the event in the database (or delete it entirely as Stefan suggested). Make sure that when the job(s) is/are picked up by the Sidekiq worker, you fetch the record, and skip additional processing there (this assumes that you're querying the database to get the latest state of the event in the job, which is general practice, and not sending all parameters to the job)