ixti/sidekiq-throttled

Incompatible with Sidekiq 5.1.3

Closed this issue · 4 comments

Recently attempted a Sidekiq upgrade from 5.0.5 -> 5.1.3 and encountered hundreds of errors originating from sidekiq-throttled. Reverting back resolved the issue.

Error message:

ArgumentError: wrong number of arguments (given 1, expected 2)
…tled-0.8.2/lib/sidekiq/throttled/fetch/unit_of_work.rb: 23:in initialize' …sidekiq-throttled-0.8.2/lib/sidekiq/throttled/fetch.rb: 36:in new'
…sidekiq-throttled-0.8.2/lib/sidekiq/throttled/fetch.rb: 36:in retrieve_work' …ruby/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb: 91:in get_one'
…ruby/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb: 101:in fetch' …ruby/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb: 84:in process_one'
…ruby/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb: 73:in run' …ndle/ruby/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/util.rb: 16:in watchdog'
…ndle/ruby/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/util.rb: 25:in `block in safe_thread'

Example Worker class:

module MyModule
  class MyWorker
    include Sidekiq::Worker
    include Sidekiq::Throttled::Worker

    sidekiq_options queue: 'email_sync'
    sidekiq_throttle concurrency: { limit: 1 }, threshold: { limit: 1, period: 1.second }

    def perform(data)
      # do stuff
    end

  end
end
ixti commented

Oh. Interesting. I will check ASAP

@ixti quick update - I've actually not been able to replicate this locally or in my staging environment 😬. One interesting thing to note is that when this was in prod, there was a period where we were queuing new jobs with sidekiq 5.1.3, but then processing them with 5.0.5 - also, tried this in staging and it seemed to work fine.

Update - seeing the same issue with matching Sidekiq client + server versions (5.0.5 or 5.1.3). Have still only been able to reproduce this issue in production, under load. See also sidekiq/sidekiq/issues/3887.

ixti commented

Can you try to upgrade json gem? Also did you (by any chance) monkey-patched Sidekiq::Throttled::Fetch? It seems like brpop returns one element instead of tuple of queue and payload. You can check what's going one like this:

class Sidekiq::Throttled::Fetch
  module Debug
    def retrieve_work
      super
    rescue
      warn "last brpop was: #{@last_work.inspect}" if defined? @last_work
      raise
    end

    def brpop
      super.tap { |work| @last_work = work }
    end
  end

  prepend Debug
end