From be7ffa2d7539d5a1946a3933cb9d242b9fac0ddc Mon Sep 17 00:00:00 2001
From: abcang <abcang1015@gmail.com>
Date: Wed, 6 Sep 2017 03:56:20 +0900
Subject: [PATCH] Do not execute the job with the same arguments as the retry
 job (#4814)

---
 app/workers/pubsubhubbub/subscribe_worker.rb |  2 +-
 config/application.rb                        |  1 +
 config/initializers/sidekiq.rb               |  3 +++
 lib/mastodon/unique_retry_job_middleware.rb  | 20 ++++++++++++++++++++
 4 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 lib/mastodon/unique_retry_job_middleware.rb

diff --git a/app/workers/pubsubhubbub/subscribe_worker.rb b/app/workers/pubsubhubbub/subscribe_worker.rb
index 7560c2671f..130c967e02 100644
--- a/app/workers/pubsubhubbub/subscribe_worker.rb
+++ b/app/workers/pubsubhubbub/subscribe_worker.rb
@@ -3,7 +3,7 @@
 class Pubsubhubbub::SubscribeWorker
   include Sidekiq::Worker
 
-  sidekiq_options queue: 'push', retry: 10, unique: :until_executed, dead: false
+  sidekiq_options queue: 'push', retry: 10, unique: :until_executed, dead: false, unique_retry: true
 
   sidekiq_retry_in do |count|
     case count
diff --git a/config/application.rb b/config/application.rb
index b6ce741477..f98f7af167 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -10,6 +10,7 @@ require_relative '../app/lib/exceptions'
 require_relative '../lib/paperclip/gif_transcoder'
 require_relative '../lib/paperclip/video_transcoder'
 require_relative '../lib/mastodon/version'
+require_relative '../lib/mastodon/unique_retry_job_middleware'
 
 Dotenv::Railtie.load
 
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index b70784d79a..61e1313364 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -13,4 +13,7 @@ end
 
 Sidekiq.configure_client do |config|
   config.redis = redis_params
+  config.client_middleware do |chain|
+    chain.add Mastodon::UniqueRetryJobMiddleware
+  end
 end
diff --git a/lib/mastodon/unique_retry_job_middleware.rb b/lib/mastodon/unique_retry_job_middleware.rb
new file mode 100644
index 0000000000..75da8a0c94
--- /dev/null
+++ b/lib/mastodon/unique_retry_job_middleware.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class Mastodon::UniqueRetryJobMiddleware
+  def call(_worker_class, item, _queue, _redis_pool)
+    return if item['unique_retry'] && retried?(item)
+    yield
+  end
+
+  private
+
+  def retried?(item)
+    # Use unique digest key of SidekiqUniqueJobs
+    unique_key = SidekiqUniqueJobs::UNIQUE_DIGEST_KEY
+    unique_digest = item[unique_key]
+    class_name = item['class']
+    retries = Sidekiq::RetrySet.new
+
+    retries.any? { |job| job.item['class'] == class_name && job.item[unique_key] == unique_digest }
+  end
+end