diff --git a/Gemfile.lock b/Gemfile.lock index bee00c6..18f5589 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM json (~> 1.8) multi_xml (>= 0.5.2) i18n (0.7.0) - json (1.8.3) + json (1.8.6) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.3) @@ -204,4 +204,4 @@ DEPENDENCIES yard (~> 0.8) BUNDLED WITH - 1.11.2 + 1.14.6 diff --git a/lib/async_cache.rb b/lib/async_cache.rb index 9440d66..664b3a6 100644 --- a/lib/async_cache.rb +++ b/lib/async_cache.rb @@ -1,20 +1,31 @@ require 'sourcify' module AsyncCache - class << self - def backend - @backend || Rails.cache - end - def backend=(backend) - @backend = backend - end + DEFAULT_OPTIONS = { + # How long Sidekiq Enterprise should hold a uniqueness lock. The default + # is 10 minutes. + uniqueness_timeout: 600, + } - def logger - @logger || Rails.logger - end - def logger=(logger) - @logger = logger - end + def self.options + @options ||= DEFAULT_OPTIONS.dup + end + def self.options=(options) + @options = options + end + + def self.backend + @backend ||= Rails.cache + end + def self.backend=(backend) + @backend = backend + end + + def self.logger + @logger ||= Rails.logger + end + def self.logger=(logger) + @logger = logger end end diff --git a/lib/async_cache/workers/sidekiq.rb b/lib/async_cache/workers/sidekiq.rb index 8368e38..36994d6 100644 --- a/lib/async_cache/workers/sidekiq.rb +++ b/lib/async_cache/workers/sidekiq.rb @@ -7,8 +7,19 @@ class SidekiqWorker include Base include Sidekiq::Worker - # Only allow one job per set of arguments to ever be in the queue - sidekiq_options :unique => :until_executed + # Pulled out into a module so it can be tested. + module Options + def self.included(mod) + if defined?(Sidekiq::Enterprise) + mod.sidekiq_options unique_for: AsyncCache.options[:uniqueness_timeout] + elsif defined?(SidekiqUniqueJobs) + # Only allow one job per set of arguments to ever be in the queue + mod.sidekiq_options unique: :until_executed + end + end + end + + include Options # Use the Sidekiq API to see if there are worker processes available to # handle the async cache jobs queue. diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c152f09..f5d9948 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,4 +11,8 @@ Rails.cache = ActiveSupport::Cache::MemoryStore.new Rails.logger = Logger.new($stdout).tap { |log| log.level = Logger::ERROR } +# Fake the `sidekiq-unique-jobs` gem being loaded. +module SidekiqUniqueJobs +end + require 'async_cache' diff --git a/spec/workers/sidekiq_spec.rb b/spec/workers/sidekiq_spec.rb index 2575025..cb1702f 100644 --- a/spec/workers/sidekiq_spec.rb +++ b/spec/workers/sidekiq_spec.rb @@ -6,6 +6,13 @@ AsyncCache::Workers::SidekiqWorker end + describe '.sidekiq_options' do + # See `spec_helper.rb` which makes it think the gem is loaded. + it 'has the uniqueness option for `sidekiq-unique-jobs`' do + expect(subject.sidekiq_options_hash).to include 'unique' + end + end + describe '::has_workers?' do it 'returns false if no Sidekiq queues are available' do allow(subject).to receive(:sidekiq_options).and_return({'queue' => 'good_queue'}) @@ -37,4 +44,34 @@ ) end end + + describe AsyncCache::Workers::SidekiqWorker::Options do + subject do + AsyncCache::Workers::SidekiqWorker::Options + end + + before do + # Set by `spec_helper.rb`. + hide_const 'SidekiqUniqueJobs' + + class Worker + end + end + + it 'sets correct option for `sidekiq-unique-jobs`' do + stub_const 'SidekiqUniqueJobs', Module.new + + expect(Worker).to receive(:sidekiq_options).with(unique: :until_executed) + + Worker.include subject + end + + it 'sets correct options for Sidekiq Enterprise' do + stub_const 'Sidekiq::Enterprise', Module.new + + expect(Worker).to receive(:sidekiq_options).with(unique_for: AsyncCache.options[:uniqueness_timeout]) + + Worker.include subject + end + end end