Search code examples
ruby-on-railsdelayed-jobsidekiq

conflict delayed_job / sidekiq


I have an app with both sidekiq and delayed job gems installed. When I trigger handle_asynchronously in active record models it appear to be handled by sidekiq while I would like to trigger delayed_job.

Is there a way to desactivate sidekiq for a specific model?


Solution

  • As I mention in the comment In order to get it working you have to redefine/basically monkey patch the handle_asynchronously method something like this

    Anywhere you like (but make sure it loaded )

    in your config/initializers/patch.rb the code look like this

    module Patch
      def handle_asynchronously(method, opts = {})
        aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
        with_method, without_method = "#{aliased_method}_with_delay#{punctuation}", "#{aliased_method}_without_delay#{punctuation}"
        define_method(with_method) do |*args|
          curr_opts = opts.clone
          curr_opts.each_key do |key|
            if (val = curr_opts[key]).is_a?(Proc)
              curr_opts[key] = if val.arity == 1
                val.call(self)
              else
                val.call
              end
            end
          end
          ## Replace this with other syntax
          # delay(curr_opts).__send__(without_method, *args)
          __delay__(curr_opts).__send__(without_method, *args)
        end
        alias_method_chain method, :delay
      end
    end
    
    Module.send(:include,Patch)
    

    And I believe rest all will follow then they way it should :)

    Reason:

    Delayed::Job include delay method on Object and Sidekiq include it delay method over ActiveRecord Hence when the class try to invoke delay it look up it ancestors class (including the Eigen Class) and it find the method define or included in ActiveRecord::Base class (which is sidekiq delay)

    why does __delay__ work because alias define the copy of the existing method which is delay method of DelayedJob , hence when you invoke the __delay__ method it invoke delay method define DelayedJob include to Object

    Note:

    Although the solution is bit patch but the it works . Keeping in mind that every direct .delay methid invocation is invoking delay method of the SideKiq and not DelayedJob to invoke the DelayedJob delay method you always has call it this way __delay__

    Suggestion :

    Monkey Patching is just a bad practice on my personal note I would rather not use 2 entirely different background processing library for a single application to achieve the same task. If the task is process thing in background why cant it be done with a single library either delayed_job or sidekiq (why it is that you required both of them )

    So the point and to simply thing make your background processing an ease with respect to future I sincerely advice you take any one of the two library for background processing and I feel that would the valid answer for your question instead of monkey patching an doing other crazy stuff

    Hope this help