diff --git a/Gemfile b/Gemfile index 61c8daa42..0c2c68fbd 100644 --- a/Gemfile +++ b/Gemfile @@ -89,6 +89,7 @@ gem "rubyzip", "~> 2.3" # Rubyzip is a ruby library for reading and writing zip gem "s3_direct_upload", "~> 0.1" # Direct Upload to Amazon S3 gem "sass-rails", "~> 6.0" # Sass adapter for the Rails asset pipeline gem "sidekiq", "~> 6.0.6" # Sidekiq is used to process background jobs with the help of Redis +gem "sidekiq-unique-jobs", "~> 6.0.21" # Ensures that Sidekiq jobs are unique when enqueued gem "sitemap_generator", "~> 6.1" # SitemapGenerator is a framework-agnostic XML Sitemap generator gem "slack-notifier", "~> 2.3" # A slim ruby wrapper for posting to slack webhooks gem "sprockets", "~> 4.0" # Sprockets is a Rack-based asset packaging system diff --git a/Gemfile.lock b/Gemfile.lock index 67892fd64..0395b6f80 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -745,6 +745,10 @@ GEM rack (~> 2.0) rack-protection (>= 2.0.0) redis (>= 4.1.0) + sidekiq-unique-jobs (6.0.21) + concurrent-ruby (~> 1.0, >= 1.0.5) + sidekiq (>= 4.0, < 7.0) + thor (~> 0) signet (0.13.0) addressable (~> 2.3) faraday (>= 0.17.3, < 2.0) @@ -987,6 +991,7 @@ DEPENDENCIES sdoc (~> 1.1) shoulda-matchers (~> 4.3.0) sidekiq (~> 6.0.6) + sidekiq-unique-jobs (~> 6.0.21) simplecov (= 0.17.1) sitemap_generator (~> 6.1) slack-notifier (~> 2.3) diff --git a/app/workers/articles/bust_cache_worker.rb b/app/workers/articles/bust_cache_worker.rb index e1876e996..53c741a8b 100644 --- a/app/workers/articles/bust_cache_worker.rb +++ b/app/workers/articles/bust_cache_worker.rb @@ -2,7 +2,7 @@ module Articles class BustCacheWorker include Sidekiq::Worker - sidekiq_options queue: :high_priority, retry: 10 + sidekiq_options queue: :high_priority, retry: 10, lock: :until_executing def perform(article_id, cache_buster = "CacheBuster") article = Article.find_by(id: article_id) diff --git a/app/workers/comments/calculate_score_worker.rb b/app/workers/comments/calculate_score_worker.rb index 0d444df7a..52344600b 100644 --- a/app/workers/comments/calculate_score_worker.rb +++ b/app/workers/comments/calculate_score_worker.rb @@ -2,7 +2,7 @@ module Comments class CalculateScoreWorker include Sidekiq::Worker - sidekiq_options queue: :medium_priority + sidekiq_options queue: :medium_priority, lock: :until_executing def perform(comment_id) comment = Comment.find_by(id: comment_id) diff --git a/app/workers/notifications/update_worker.rb b/app/workers/notifications/update_worker.rb index 51cbca345..1e2867ae6 100644 --- a/app/workers/notifications/update_worker.rb +++ b/app/workers/notifications/update_worker.rb @@ -2,7 +2,7 @@ module Notifications class UpdateWorker include Sidekiq::Worker - sidekiq_options queue: :medium_priority, retry: 10 + sidekiq_options queue: :medium_priority, retry: 10, lock: :until_executing def perform(notifiable_id, notifiable_class, action = nil) raise InvalidNotifiableForUpdate, notifiable_class unless %w[Article Comment].include?(notifiable_class) diff --git a/app/workers/search/index_to_elasticsearch_worker.rb b/app/workers/search/index_to_elasticsearch_worker.rb index c01081f07..cf16835c6 100644 --- a/app/workers/search/index_to_elasticsearch_worker.rb +++ b/app/workers/search/index_to_elasticsearch_worker.rb @@ -2,7 +2,7 @@ module Search class IndexToElasticsearchWorker include Sidekiq::Worker - sidekiq_options queue: :high_priority + sidekiq_options queue: :high_priority, lock: :until_executing def perform(object_class, id) # PodcastEpisodes and Articles share an index so their IDs are prepended with their class names diff --git a/app/workers/search/remove_from_elasticsearch_index_worker.rb b/app/workers/search/remove_from_elasticsearch_index_worker.rb index e74353a7d..3f5289864 100644 --- a/app/workers/search/remove_from_elasticsearch_index_worker.rb +++ b/app/workers/search/remove_from_elasticsearch_index_worker.rb @@ -2,7 +2,7 @@ module Search class RemoveFromElasticsearchIndexWorker include Sidekiq::Worker - sidekiq_options queue: :medium_priority + sidekiq_options queue: :medium_priority, lock: :until_executing def perform(search_class, id) search_class.safe_constantize.delete_document(id) diff --git a/config/initializers/sidekiq_unique_jobs.rb b/config/initializers/sidekiq_unique_jobs.rb new file mode 100644 index 000000000..0261ad516 --- /dev/null +++ b/config/initializers/sidekiq_unique_jobs.rb @@ -0,0 +1,3 @@ +SidekiqUniqueJobs.configure do |config| + config.enabled = !Rails.env.test? +end diff --git a/config/routes.rb b/config/routes.rb index 1ab23b4d8..293d6ce4c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,8 @@ Rails.application.routes.draw do } require "sidekiq/web" + require "sidekiq_unique_jobs/web" + authenticated :user, ->(user) { user.tech_admin? } do Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base] Sidekiq::Web.set :sessions, Rails.application.config.session_options