Skip to content

Instantly share code, notes, and snippets.

@nertzy
Last active August 12, 2020 18:52
Show Gist options
  • Save nertzy/74d4fbab3440d56b8bda2241b4eb0c4e to your computer and use it in GitHub Desktop.
Save nertzy/74d4fbab3440d56b8bda2241b4eb0c4e to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
require "sidekiq-ent/unique"
# In order to prevent duplicate unique jobs, Sidekiq Enterprise generates a
# hash of the job arguments. Because we are using Active Job, the arguments
# that Sidekiq receives include the job id and a timestamp of when the job was
# enqueued, both of which are virtually guaranteed to be unique.
#
# To work around this, we intercept and filter these arguments out around
# the method that calculates this hash.
#
# See https://github.com/mperham/sidekiq/issues/4667
module SidekiqActiveJobUniqueFix
module ClientInstanceMethods
def call(worker, job, queue, redis_pool)
return super unless active_job?(job)
original_job_args = replace_job_args_for_unique_check(job)
# super will yield to our block...
super do
restore_job_args(job, original_job_args)
# ... and our block will yield to the original block.
yield
end
end
private
def active_job?(job)
job["class"] == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
end
def replace_job_args_for_unique_check(job)
original_job_args = job["args"]
job["args"] = unique_job_args(original_job_args[0])
original_job_args
end
def unique_job_args(job_args)
[job_args["job_class"], *job_args["arguments"]]
end
def restore_job_args(job, original_job_args)
job["args"] = original_job_args
end
end
end
Sidekiq::Enterprise::Unique::Client.class_eval { prepend SidekiqActiveJobUniqueFix::ClientInstanceMethods }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment