diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 000000000..ceb20c34a --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,36 @@ + +Lint/HandleExceptions: + Enabled: true + +Lint/UselessAssignment: + Enabled: true + +Metrics/AbcSize: + Max: 38 + +Metrics/CyclomaticComplexity: + Max: 7 + +Metrics/LineLength: + Max: 108 + +Metrics/MethodLength: + Max: 13 + +Metrics/PerceivedComplexity: + Max: 8 + +Style/AccessorMethodName: + Enabled: true + +Style/ConstantName: + Enabled: true + +Style/Documentation: + Enabled: false + +Style/FileName: + Enabled: true + +Style/GlobalVars: + Enabled: true diff --git a/README.md b/README.md index 2240b99cb..beae0aca3 100644 --- a/README.md +++ b/README.md @@ -41,12 +41,12 @@ Requiring the gem in your gemfile should be sufficient to enable unique jobs. ### Finer Control over Uniqueness -Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be _transient_. For this use-case, you need to set `SidekiqUniqueJobs::Config.unique_args_enabled` to true in an initializer, and then defined either `unique_args` method, or a ruby proc. +Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be _transient_. For this use-case, you need to set `SidekiqUniqueJobs.config.unique_args_enabled` to true in an initializer, and then defined either `unique_args` method, or a ruby proc. The unique_args method need to return an array of values to use for uniqueness check. ```ruby -SidekiqUniqueJobs::Config.unique_args_enabled = true +SidekiqUniqueJobs.config.unique_args_enabled = true ``` The method or the proc can return a modified version of args without the transient arguments included, as shown below: diff --git a/Rakefile b/Rakefile index 65cc6bf96..113a2b8ee 100644 --- a/Rakefile +++ b/Rakefile @@ -1,9 +1,11 @@ #!/usr/bin/env rake -require "rubygems" -require "bundler/setup" -require "bundler/gem_tasks" +require 'rubygems' +require 'bundler/setup' +require 'bundler/gem_tasks' require 'rspec/core/rake_task' +require 'rubocop/rake_task' +RuboCop::RakeTask.new(:style) RSpec::Core::RakeTask.new(:spec) -task :default => :spec \ No newline at end of file +task default: [:spec, :style] diff --git a/lib/sidekiq-unique-jobs.rb b/lib/sidekiq-unique-jobs.rb deleted file mode 100644 index e4328d82d..000000000 --- a/lib/sidekiq-unique-jobs.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'yaml' if RUBY_VERSION.include?('2.0.0') -require 'sidekiq-unique-jobs/middleware' -require "sidekiq-unique-jobs/version" -require "sidekiq-unique-jobs/config" -require "sidekiq-unique-jobs/payload_helper" - -module SidekiqUniqueJobs - def self.config - SidekiqUniqueJobs::Config - end -end \ No newline at end of file diff --git a/lib/sidekiq-unique-jobs/config.rb b/lib/sidekiq-unique-jobs/config.rb deleted file mode 100644 index afad711fe..000000000 --- a/lib/sidekiq-unique-jobs/config.rb +++ /dev/null @@ -1,44 +0,0 @@ -module SidekiqUniqueJobs - class Config - def self.unique_prefix=(prefix) - @unique_prefix = prefix - end - - def self.unique_prefix - @unique_prefix || "sidekiq_unique" - end - - def self.unique_args_enabled=(enabled) - @unique_args_enabled = enabled - end - - def self.unique_args_enabled? - @unique_args_enabled || false - end - - def self.default_expiration=(expiration) - @expiration = expiration - end - - def self.default_expiration - @expiration || 30 * 60 - end - - def self.default_unlock_order=(order) - @default_unlock_order = order - end - - def self.default_unlock_order - @default_unlock_order || :after_yield - end - - def self.testing_enabled? - if Sidekiq.const_defined?('Testing') && Sidekiq::Testing.enabled? - require 'sidekiq-unique-jobs/testing' - return true - end - - false - end - end -end diff --git a/lib/sidekiq-unique-jobs/payload_helper.rb b/lib/sidekiq-unique-jobs/payload_helper.rb deleted file mode 100644 index 68d74a4b7..000000000 --- a/lib/sidekiq-unique-jobs/payload_helper.rb +++ /dev/null @@ -1,30 +0,0 @@ -module SidekiqUniqueJobs - class PayloadHelper - def self.get_payload(klass, queue, *args) - unique_on_all_queues = false - if SidekiqUniqueJobs::Config.unique_args_enabled? - worker_class = klass.constantize - args = yield_unique_args(worker_class, *args) - unique_on_all_queues = worker_class.get_sidekiq_options['unique_on_all_queues'] - end - md5_arguments = {:class => klass, :args => args} - md5_arguments[:queue] = queue unless unique_on_all_queues - "#{SidekiqUniqueJobs::Config.unique_prefix}:#{Digest::MD5.hexdigest(Sidekiq.dump_json(md5_arguments))}" - end - - def self.yield_unique_args(worker_class, args) - unique_args = worker_class.get_sidekiq_options['unique_args'] - filtered_args = if unique_args - case unique_args - when Proc - unique_args.call(args) - when Symbol - worker_class.send(unique_args, *args) if worker_class.respond_to?(unique_args) - end - end - filtered_args || args - rescue NameError # if we can't instantiate the class, we just fallback to not filtering args - args - end - end -end diff --git a/lib/sidekiq_unique_jobs.rb b/lib/sidekiq_unique_jobs.rb new file mode 100644 index 000000000..300a337a4 --- /dev/null +++ b/lib/sidekiq_unique_jobs.rb @@ -0,0 +1,27 @@ +require 'yaml' if RUBY_VERSION.include?('2.0.0') +require 'sidekiq_unique_jobs/middleware' +require 'sidekiq_unique_jobs/version' +require 'sidekiq_unique_jobs/config' +require 'sidekiq_unique_jobs/payload_helper' +require 'ostruct' + +module SidekiqUniqueJobs + module_function + + def config + @config ||= Config.new( + unique_prefix: 'sidekiq_unique', + unique_args_enabled: false, + default_expiration: 30 * 60, + default_unlock_order: :after_yield + ) + end + + def unique_args_enabled? + config.unique_args_enabled + end + + def configure + yield configuration + end +end diff --git a/lib/sidekiq_unique_jobs/config.rb b/lib/sidekiq_unique_jobs/config.rb new file mode 100644 index 000000000..0a0cd4f45 --- /dev/null +++ b/lib/sidekiq_unique_jobs/config.rb @@ -0,0 +1,47 @@ +module SidekiqUniqueJobs + class Config < OpenStruct + CONFIG_ACCESSORS = [ + :unique_prefix, + :unique_args_enabled, + :default_expiration, + :default_unlock_order + ] + + class << self + warn('This method has been deprecated. See readme for information') + CONFIG_ACCESSORS.each do |method| + define_method(method) do + warn('This method has been deprecated. See readme for information') + config.send(method) + end + + define_method("#{method}=") do |obj| + warn('This method has been deprecated. See readme for information') + config.send("#{method}=", obj) + end + end + + def unique_args_enabled? + warn('This method has been deprecated. See readme for information') + config.unique_args_enabled + end + + def config + SidekiqUniqueJobs.config + end + end + + def testing_enabled? + if Sidekiq.const_defined?('Testing') && Sidekiq::Testing.enabled? + require 'sidekiq_unique_jobs/testing' + return true + end + + false + end + + def unique_args_enabled? + config.unique_args_enabled + end + end +end diff --git a/lib/sidekiq-unique-jobs/middleware.rb b/lib/sidekiq_unique_jobs/middleware.rb similarity index 68% rename from lib/sidekiq-unique-jobs/middleware.rb rename to lib/sidekiq_unique_jobs/middleware.rb index ef99d1fbb..20477f862 100644 --- a/lib/sidekiq-unique-jobs/middleware.rb +++ b/lib/sidekiq_unique_jobs/middleware.rb @@ -2,11 +2,11 @@ Sidekiq.configure_server do |config| config.server_middleware do |chain| - require 'sidekiq-unique-jobs/middleware/server/unique_jobs' + require 'sidekiq_unique_jobs/middleware/server/unique_jobs' chain.add SidekiqUniqueJobs::Middleware::Server::UniqueJobs end config.client_middleware do |chain| - require 'sidekiq-unique-jobs/middleware/client/unique_jobs' + require 'sidekiq_unique_jobs/middleware/client/unique_jobs' chain.add SidekiqUniqueJobs::Middleware::Client::UniqueJobs end @@ -14,7 +14,7 @@ Sidekiq.configure_client do |config| config.client_middleware do |chain| - require 'sidekiq-unique-jobs/middleware/client/unique_jobs' + require 'sidekiq_unique_jobs/middleware/client/unique_jobs' chain.add SidekiqUniqueJobs::Middleware::Client::UniqueJobs end end diff --git a/lib/sidekiq-unique-jobs/middleware/client/connectors/connector.rb b/lib/sidekiq_unique_jobs/middleware/client/connectors/connector.rb similarity index 88% rename from lib/sidekiq-unique-jobs/middleware/client/connectors/connector.rb rename to lib/sidekiq_unique_jobs/middleware/client/connectors/connector.rb index dc69f0479..365e67fc1 100644 --- a/lib/sidekiq-unique-jobs/middleware/client/connectors/connector.rb +++ b/lib/sidekiq_unique_jobs/middleware/client/connectors/connector.rb @@ -3,8 +3,8 @@ module Middleware module Client module Connectors class Connector - def self.eligible?(redis_pool = nil) - raise 'Should be implemented in a sub class' + def self.eligible?(_redis_pool = nil) + fail 'Should be implemented in a sub class' end def self.review_unique(worker_class, item, queue, redis_pool = nil) @@ -33,14 +33,14 @@ def unique_for_connection? conn.watch(payload_hash) if conn.get(payload_hash).to_i == 1 || - (conn.get(payload_hash).to_i == 2 && item['at']) + (conn.get(payload_hash).to_i == 2 && item['at']) # if the job is already queued, or is already scheduled and # we're trying to schedule again, abort conn.unwatch else # if the job was previously scheduled and is now being queued, # or we've never seen it before - expires_at = unique_job_expiration || SidekiqUniqueJobs::Config.default_expiration + expires_at = unique_job_expiration || SidekiqUniqueJobs.config.default_expiration expires_at = ((Time.at(item['at']) - Time.now.utc) + expires_at).to_i if item['at'] unique = conn.multi do @@ -52,7 +52,7 @@ def unique_for_connection? end def conn - raise 'Should be implemented in a sub class' + fail 'Should be implemented in a sub class' end def payload_hash diff --git a/lib/sidekiq-unique-jobs/middleware/client/connectors/redis_pool.rb b/lib/sidekiq_unique_jobs/middleware/client/connectors/redis_pool.rb similarity index 84% rename from lib/sidekiq-unique-jobs/middleware/client/connectors/redis_pool.rb rename to lib/sidekiq_unique_jobs/middleware/client/connectors/redis_pool.rb index 225e3ae57..1e972876d 100644 --- a/lib/sidekiq-unique-jobs/middleware/client/connectors/redis_pool.rb +++ b/lib/sidekiq_unique_jobs/middleware/client/connectors/redis_pool.rb @@ -1,4 +1,4 @@ -require 'sidekiq-unique-jobs/middleware/client/connectors/connector' +require 'sidekiq_unique_jobs/middleware/client/connectors/connector' module SidekiqUniqueJobs module Middleware diff --git a/lib/sidekiq-unique-jobs/middleware/client/connectors/sidekiq_redis.rb b/lib/sidekiq_unique_jobs/middleware/client/connectors/sidekiq_redis.rb similarity index 72% rename from lib/sidekiq-unique-jobs/middleware/client/connectors/sidekiq_redis.rb rename to lib/sidekiq_unique_jobs/middleware/client/connectors/sidekiq_redis.rb index fa1e88c60..290951cea 100644 --- a/lib/sidekiq-unique-jobs/middleware/client/connectors/sidekiq_redis.rb +++ b/lib/sidekiq_unique_jobs/middleware/client/connectors/sidekiq_redis.rb @@ -1,11 +1,11 @@ -require 'sidekiq-unique-jobs/middleware/client/connectors/connector' +require 'sidekiq_unique_jobs/middleware/client/connectors/connector' module SidekiqUniqueJobs module Middleware module Client module Connectors class SidekiqRedis < Connector - def self.eligible?(redis_pool = nil) + def self.eligible?(_redis_pool = nil) true end diff --git a/lib/sidekiq-unique-jobs/middleware/client/connectors/testing_fake.rb b/lib/sidekiq_unique_jobs/middleware/client/connectors/testing_fake.rb similarity index 60% rename from lib/sidekiq-unique-jobs/middleware/client/connectors/testing_fake.rb rename to lib/sidekiq_unique_jobs/middleware/client/connectors/testing_fake.rb index e5d6b18f7..511f05889 100644 --- a/lib/sidekiq-unique-jobs/middleware/client/connectors/testing_fake.rb +++ b/lib/sidekiq_unique_jobs/middleware/client/connectors/testing_fake.rb @@ -1,12 +1,12 @@ -require 'sidekiq-unique-jobs/middleware/client/connectors/connector' +require 'sidekiq_unique_jobs/middleware/client/connectors/connector' module SidekiqUniqueJobs module Middleware module Client module Connectors class TestingFake < Connector - def self.eligible?(redis_pool = nil) - Config.testing_enabled? && Sidekiq::Testing.fake? + def self.eligible?(_redis_pool = nil) + SidekiqUniqueJobs.config.testing_enabled? && Sidekiq::Testing.fake? end private diff --git a/lib/sidekiq-unique-jobs/middleware/client/connectors/testing_inline.rb b/lib/sidekiq_unique_jobs/middleware/client/connectors/testing_inline.rb similarity index 68% rename from lib/sidekiq-unique-jobs/middleware/client/connectors/testing_inline.rb rename to lib/sidekiq_unique_jobs/middleware/client/connectors/testing_inline.rb index 851347e17..6e0a9ae23 100644 --- a/lib/sidekiq-unique-jobs/middleware/client/connectors/testing_inline.rb +++ b/lib/sidekiq_unique_jobs/middleware/client/connectors/testing_inline.rb @@ -1,13 +1,13 @@ -require 'sidekiq-unique-jobs/middleware/client/connectors/connector' -require 'sidekiq-unique-jobs/middleware/server/unique_jobs' +require 'sidekiq_unique_jobs/middleware/client/connectors/connector' +require 'sidekiq_unique_jobs/middleware/server/unique_jobs' module SidekiqUniqueJobs module Middleware module Client module Connectors class TestingInline < Connector - def self.eligible?(redis_pool = nil) - Config.testing_enabled? && Sidekiq::Testing.inline? + def self.eligible?(_redis_pool = nil) + SidekiqUniqueJobs.config.testing_enabled? && Sidekiq::Testing.inline? end def review_unique diff --git a/lib/sidekiq-unique-jobs/middleware/client/unique_jobs.rb b/lib/sidekiq_unique_jobs/middleware/client/unique_jobs.rb similarity index 68% rename from lib/sidekiq-unique-jobs/middleware/client/unique_jobs.rb rename to lib/sidekiq_unique_jobs/middleware/client/unique_jobs.rb index 3dc1d3187..7a090bcc5 100644 --- a/lib/sidekiq-unique-jobs/middleware/client/unique_jobs.rb +++ b/lib/sidekiq_unique_jobs/middleware/client/unique_jobs.rb @@ -1,14 +1,14 @@ require 'digest' -require 'sidekiq-unique-jobs/middleware/client/connectors/testing_fake' -require 'sidekiq-unique-jobs/middleware/client/connectors/testing_inline' -require 'sidekiq-unique-jobs/middleware/client/connectors/redis_pool' -require 'sidekiq-unique-jobs/middleware/client/connectors/sidekiq_redis' +require 'sidekiq_unique_jobs/middleware/client/connectors/testing_fake' +require 'sidekiq_unique_jobs/middleware/client/connectors/testing_inline' +require 'sidekiq_unique_jobs/middleware/client/connectors/redis_pool' +require 'sidekiq_unique_jobs/middleware/client/connectors/sidekiq_redis' module SidekiqUniqueJobs module Middleware module Client class UniqueJobs - Connectors = [ + CONNECTORS = [ Connectors::TestingFake, Connectors::TestingInline, Connectors::RedisPool, @@ -36,17 +36,16 @@ def unique_enabled? end def connector - Connectors.detect { |conn| conn.eligible?(redis_pool) } + CONNECTORS.detect { |conn| conn.eligible?(redis_pool) } end # Attempt to constantize a string worker_class argument, always # failing back to the original argument. def worker_class_constantize(worker_class) - if worker_class.is_a?(String) - worker_class.constantize rescue worker_class - else - worker_class - end + return worker_class unless worker_class.is_a?(String) + worker_class.constantize + rescue NameError + worker_class end end end diff --git a/lib/sidekiq-unique-jobs/middleware/server/unique_jobs.rb b/lib/sidekiq_unique_jobs/middleware/server/unique_jobs.rb similarity index 77% rename from lib/sidekiq-unique-jobs/middleware/server/unique_jobs.rb rename to lib/sidekiq_unique_jobs/middleware/server/unique_jobs.rb index d36036423..be2de8736 100644 --- a/lib/sidekiq-unique-jobs/middleware/server/unique_jobs.rb +++ b/lib/sidekiq_unique_jobs/middleware/server/unique_jobs.rb @@ -6,10 +6,10 @@ module Server class UniqueJobs attr_reader :unlock_order, :redis_pool - def call(worker, item, queue, redis_pool = nil) + def call(worker, item, _queue, redis_pool = nil) @redis_pool = redis_pool - set_unlock_order(worker.class) + decide_unlock_order(worker.class) lock_key = payload_hash(item) unlocked = before_yield? ? unlock(lock_key).inspect : 0 @@ -20,12 +20,12 @@ def call(worker, item, queue, redis_pool = nil) end end - def set_unlock_order(klass) + def decide_unlock_order(klass) @unlock_order = if unlock_order_configured?(klass) - klass.get_sidekiq_options['unique_unlock_order'] - else - default_unlock_order - end + klass.get_sidekiq_options['unique_unlock_order'] + else + default_unlock_order + end end def unlock_order_configured?(klass) @@ -34,7 +34,7 @@ def unlock_order_configured?(klass) end def default_unlock_order - SidekiqUniqueJobs::Config.default_unlock_order + SidekiqUniqueJobs.config.default_unlock_order end def before_yield? @@ -60,7 +60,7 @@ def logger end def connector - return SidekiqUniqueJobs.redis_mock { |conn| conn } if Config.testing_enabled? + return SidekiqUniqueJobs.redis_mock { |conn| conn } if SidekiqUniqueJobs.config.testing_enabled? return redis_pool.with { |conn| conn } if redis_pool Sidekiq.redis { |conn| conn } end diff --git a/lib/sidekiq_unique_jobs/payload_helper.rb b/lib/sidekiq_unique_jobs/payload_helper.rb new file mode 100644 index 000000000..ecf10d871 --- /dev/null +++ b/lib/sidekiq_unique_jobs/payload_helper.rb @@ -0,0 +1,42 @@ +module SidekiqUniqueJobs + class PayloadHelper + def self.config + SidekiqUniqueJobs.config + end + + def self.get_payload(klass, queue, *args) + unique_on_all_queues = false + if config.unique_args_enabled + worker_class = klass.constantize + args = yield_unique_args(worker_class, *args) + unique_on_all_queues = + worker_class.get_sidekiq_options['unique_on_all_queues'] + end + md5_arguments = { class: klass, args: args } + md5_arguments[:queue] = queue unless unique_on_all_queues + "#{config.unique_prefix}:" \ + "#{Digest::MD5.hexdigest(Sidekiq.dump_json(md5_arguments))}" + end + + def self.yield_unique_args(worker_class, args) + unique_args = worker_class.get_sidekiq_options['unique_args'] + filtered_args(worker_class, unique_args, args) + rescue NameError + # fallback to not filtering args when class can't be instantiated + args + end + + def self.filtered_args(worker_class, unique_args, args) + case unique_args + when Proc + unique_args.call(args) + when Symbol + if worker_class.respond_to?(unique_args) + worker_class.send(unique_args, *args) + end + else + args + end + end + end +end diff --git a/lib/sidekiq-unique-jobs/testing.rb b/lib/sidekiq_unique_jobs/testing.rb similarity index 66% rename from lib/sidekiq-unique-jobs/testing.rb rename to lib/sidekiq_unique_jobs/testing.rb index 55f40c49c..4db874746 100644 --- a/lib/sidekiq-unique-jobs/testing.rb +++ b/lib/sidekiq_unique_jobs/testing.rb @@ -1,6 +1,6 @@ require 'mock_redis' module SidekiqUniqueJobs def self.redis_mock - @redis_mock ||= MockRedis.new + @redis_mock ||= MockRedis.new end -end \ No newline at end of file +end diff --git a/lib/sidekiq-unique-jobs/version.rb b/lib/sidekiq_unique_jobs/version.rb similarity index 59% rename from lib/sidekiq-unique-jobs/version.rb rename to lib/sidekiq_unique_jobs/version.rb index 2d3454a1f..57afe471a 100644 --- a/lib/sidekiq-unique-jobs/version.rb +++ b/lib/sidekiq_unique_jobs/version.rb @@ -1,3 +1,3 @@ module SidekiqUniqueJobs - VERSION = "3.0.4" + VERSION = '3.0.4' end diff --git a/sidekiq-unique-jobs.gemspec b/sidekiq-unique-jobs.gemspec index 72acd304d..c71e1e8c9 100644 --- a/sidekiq-unique-jobs.gemspec +++ b/sidekiq-unique-jobs.gemspec @@ -1,24 +1,25 @@ # -*- encoding: utf-8 -*- -require File.expand_path('../lib/sidekiq-unique-jobs/version', __FILE__) +require File.expand_path('../lib/sidekiq_unique_jobs/version', __FILE__) Gem::Specification.new do |gem| - gem.authors = ["Mikael Henriksson"] - gem.email = ["mikael@zoolutions.se"] - gem.description = gem.summary = "The unique jobs that were removed from sidekiq" - gem.homepage = "https://github.com/mhenrixon/sidekiq-unique-jobs" - gem.license = "LGPL-3.0" + gem.authors = ['Mikael Henriksson'] + gem.email = ['mikael@zoolutions.se'] + gem.description = gem.summary = 'The unique jobs that were removed from sidekiq' + gem.homepage = 'https://github.com/mhenrixon/sidekiq-unique-jobs' + gem.license = 'LGPL-3.0' # gem.executables = [''] gem.files = `git ls-files`.split("\n") gem.test_files = `git ls-files -- test/*`.split("\n") - gem.name = "sidekiq-unique-jobs" - gem.require_paths = ["lib"] + gem.name = 'sidekiq-unique-jobs' + gem.require_paths = ['lib'] gem.version = SidekiqUniqueJobs::VERSION - gem.add_dependency 'sidekiq', '>= 2.6' + gem.add_dependency 'sidekiq', '>= 2.6' gem.add_development_dependency 'mock_redis' gem.add_development_dependency 'rspec', '~> 3.1.0' gem.add_development_dependency 'rake' gem.add_development_dependency 'rspec-sidekiq' gem.add_development_dependency 'activesupport', '>= 3' + gem.add_development_dependency 'rubocop' gem.add_development_dependency 'simplecov' end diff --git a/spec/lib/client_spec.rb b/spec/lib/client_spec.rb index fab79fe6d..1d5bfc8dd 100644 --- a/spec/lib/client_spec.rb +++ b/spec/lib/client_spec.rb @@ -1,98 +1,98 @@ require 'spec_helper' require 'celluloid' require 'sidekiq/worker' -require "sidekiq-unique-jobs" +require 'sidekiq_unique_jobs' require 'sidekiq/scheduled' -require 'sidekiq-unique-jobs/middleware/server/unique_jobs' +require 'sidekiq_unique_jobs/middleware/server/unique_jobs' -describe "Client" do +describe 'Client' do describe 'with real redis' do before do Sidekiq.redis = REDIS - Sidekiq.redis {|c| c.flushdb } - QueueWorker.sidekiq_options :unique => nil, :unique_job_expiration => nil + Sidekiq.redis(&:flushdb) + QueueWorker.sidekiq_options unique: nil, unique_job_expiration: nil end class QueueWorker include Sidekiq::Worker - sidekiq_options :queue => 'customqueue' - def perform(x) + sidekiq_options queue: 'customqueue' + def perform(_x) end end class PlainClass - def run(x) + def run(_x) end end it 'does not push duplicate messages when configured for unique only' do - QueueWorker.sidekiq_options :unique => true + QueueWorker.sidekiq_options unique: true 10.times { Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) } - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + result = Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(result).to eq 1 end it 'does push duplicate messages to different queues' do - QueueWorker.sidekiq_options :unique => true + QueueWorker.sidekiq_options unique: true Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue2', 'args' => [1, 2]) - q1_length = Sidekiq.redis {|c| c.llen("queue:customqueue") } - q2_length = Sidekiq.redis {|c| c.llen("queue:customqueue2") } + q1_length = Sidekiq.redis { |c| c.llen('queue:customqueue') } + q2_length = Sidekiq.redis { |c| c.llen('queue:customqueue2') } expect(q1_length).to eq 1 expect(q2_length).to eq 1 end it 'does not queue duplicates when when calling delay' do 10.times { PlainClass.delay(unique: true, queue: 'customqueue').run(1) } - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + result = Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(result).to eq 1 end it 'does not schedule duplicates when calling perform_in' do - QueueWorker.sidekiq_options :unique => true + QueueWorker.sidekiq_options unique: true 10.times { QueueWorker.perform_in(60, [1, 2]) } - result = Sidekiq.redis { |c| c.zcount("schedule", -1, Time.now.to_f + 2 * 60) } + result = Sidekiq.redis { |c| c.zcount('schedule', -1, Time.now.to_f + 2 * 60) } expect(result).to eq 1 end it 'enqueues previously scheduled job' do - QueueWorker.sidekiq_options :unique => true + QueueWorker.sidekiq_options unique: true QueueWorker.perform_in(60 * 60, 1, 2) # time passes and the job is pulled off the schedule: Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + result = Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(result).to eq 1 end it 'sets an expiration when provided by sidekiq options' do one_hour_expiration = 60 * 60 - QueueWorker.sidekiq_options :unique => true, :unique_job_expiration => one_hour_expiration + QueueWorker.sidekiq_options unique: true, unique_job_expiration: one_hour_expiration Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) - payload_hash = SidekiqUniqueJobs::PayloadHelper.get_payload("QueueWorker", "customqueue", [1, 2]) - actual_expires_at = Sidekiq.redis {|c| c.ttl(payload_hash) } + payload_hash = SidekiqUniqueJobs::PayloadHelper.get_payload('QueueWorker', 'customqueue', [1, 2]) + actual_expires_at = Sidekiq.redis { |c| c.ttl(payload_hash) } - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(actual_expires_at).to be_within(2).of(one_hour_expiration) end it 'does push duplicate messages when not configured for unique only' do - QueueWorker.sidekiq_options :unique => false + QueueWorker.sidekiq_options unique: false 10.times { Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) } - expect(Sidekiq.redis {|c| c.llen("queue:customqueue") }).to eq 10 + expect(Sidekiq.redis { |c| c.llen('queue:customqueue') }).to eq 10 - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + result = Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(result).to eq 10 end describe 'when unique_args is defined' do - before { SidekiqUniqueJobs::Config.unique_args_enabled = true } - after { SidekiqUniqueJobs::Config.unique_args_enabled = false } + before { SidekiqUniqueJobs.config.unique_args_enabled = true } + after { SidekiqUniqueJobs.config.unique_args_enabled = false } class QueueWorkerWithFilterMethod < QueueWorker - sidekiq_options :unique => true, :unique_args => :args_filter + sidekiq_options unique: true, unique_args: :args_filter def self.args_filter(*args) args.first @@ -100,19 +100,27 @@ def self.args_filter(*args) end class QueueWorkerWithFilterProc < QueueWorker - # slightly contrived example of munging args to the worker and removing a random bit. - sidekiq_options :unique => true, :unique_args => lambda { |args| a = args.last.dup; a.delete(:random); [ args.first, a ] } + # slightly contrived example of munging args to the + # worker and removing a random bit. + sidekiq_options unique: true, unique_args: (lambda do |args| + a = args.last.dup + a.delete(:random) + [args.first, a] + end) end it 'does not push duplicate messages based on args filter method' do expect(QueueWorkerWithFilterMethod).to respond_to(:args_filter) expect(QueueWorkerWithFilterMethod.get_sidekiq_options['unique_args']).to eq :args_filter - - for i in (0..10).to_a - Sidekiq::Client.push('class' => QueueWorkerWithFilterMethod, 'queue' => 'customqueue', 'args' => [1, i]) + (0..10).each do |i| + Sidekiq::Client.push( + 'class' => QueueWorkerWithFilterMethod, + 'queue' => 'customqueue', + 'args' => [1, i] + ) end - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + result = Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(result).to eq 1 end @@ -120,20 +128,24 @@ class QueueWorkerWithFilterProc < QueueWorker expect(QueueWorkerWithFilterProc.get_sidekiq_options['unique_args']).to be_a(Proc) 10.times do - Sidekiq::Client.push('class' => QueueWorkerWithFilterProc, 'queue' => 'customqueue', 'args' => [ 1, {:random => rand(), :name => "foobar"} ]) + Sidekiq::Client.push( + 'class' => QueueWorkerWithFilterProc, + 'queue' => 'customqueue', + 'args' => [1, { random: rand, name: 'foobar' }] + ) end - result = Sidekiq.redis {|c| c.llen("queue:customqueue") } + result = Sidekiq.redis { |c| c.llen('queue:customqueue') } expect(result).to eq 1 end describe 'when unique_on_all_queues is set' do - before { QueueWorker.sidekiq_options :unique => true, :unique_on_all_queues => true } - before { QueueWorker.sidekiq_options :unique => true } + before { QueueWorker.sidekiq_options unique: true, unique_on_all_queues: true } + before { QueueWorker.sidekiq_options unique: true } it 'does not push duplicate messages on different queues' do Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) Sidekiq::Client.push('class' => QueueWorker, 'queue' => 'customqueue2', 'args' => [1, 2]) - q1_length = Sidekiq.redis {|c| c.llen("queue:customqueue") } - q2_length = Sidekiq.redis {|c| c.llen("queue:customqueue2") } + q1_length = Sidekiq.redis { |c| c.llen('queue:customqueue') } + q2_length = Sidekiq.redis { |c| c.llen('queue:customqueue2') } expect(q1_length).to eq 1 expect(q2_length).to eq 0 end @@ -145,16 +157,16 @@ class QueueWorkerWithFilterProc < QueueWorker # jobs are set around the same time as the scheduled job itself feel free to improve. it 'expires the payload_hash when a scheduled job is scheduled at' do require 'active_support/all' - QueueWorker.sidekiq_options :unique => true + QueueWorker.sidekiq_options unique: true at = 15.minutes.from_now - expected_expires_at = (Time.at(at) - Time.now.utc) + SidekiqUniqueJobs::Config.default_expiration + expected_expires_at = (Time.at(at) - Time.now.utc) + SidekiqUniqueJobs.config.default_expiration QueueWorker.perform_in(at, 'mike') - payload_hash = SidekiqUniqueJobs::PayloadHelper.get_payload("QueueWorker", "customqueue", ['mike']) + payload_hash = SidekiqUniqueJobs::PayloadHelper.get_payload('QueueWorker', 'customqueue', ['mike']) # deconstruct this into a time format we can use to get a decent delta for - actual_expires_at = Sidekiq.redis {|c| c.ttl(payload_hash) } + actual_expires_at = Sidekiq.redis { |c| c.ttl(payload_hash) } expect(actual_expires_at).to be_within(2).of(expected_expires_at) end diff --git a/spec/lib/middleware/server/unique_jobs_spec.rb b/spec/lib/middleware/server/unique_jobs_spec.rb index a94ed1e69..3d54a4fef 100644 --- a/spec/lib/middleware/server/unique_jobs_spec.rb +++ b/spec/lib/middleware/server/unique_jobs_spec.rb @@ -6,48 +6,48 @@ module Server describe UniqueJobs do describe '#unlock_order_configured?' do context "when class isn't a Sidekiq::Worker" do - it "returns false" do + it 'returns false' do expect(subject.unlock_order_configured?(Class)) .to eq(false) end end - context "when get_sidekiq_options[:unique_unlock_order] is nil" do - it "returns false" do + context 'when get_sidekiq_options[:unique_unlock_order] is nil' do + it 'returns false' do expect(subject.unlock_order_configured?(MyWorker)) .to eq(false) end end - it "returns true when unique_unlock_order has been set" do + it 'returns true when unique_unlock_order has been set' do UniqueWorker.sidekiq_options unique_unlock_order: :before_yield expect(subject.unlock_order_configured?(UniqueWorker)) .to eq(true) end end - describe '#set_unlock_order' do - context "when worker has specified unique_unlock_order" do - it "changes unlock_order to the configured value" do + describe '#decide_unlock_order' do + context 'when worker has specified unique_unlock_order' do + it 'changes unlock_order to the configured value' do UniqueWorker.sidekiq_options unique_unlock_order: :before_yield expect do - subject.set_unlock_order(UniqueWorker) + subject.decide_unlock_order(UniqueWorker) end.to change { subject.unlock_order }.to :before_yield end end context "when worker hasn't specified unique_unlock_order" do - it "falls back to configured default_unlock_order" do - SidekiqUniqueJobs::Config.default_unlock_order = :before_yield + it 'falls back to configured default_unlock_order' do + SidekiqUniqueJobs.config.default_unlock_order = :before_yield expect do - subject.set_unlock_order(UniqueWorker) + subject.decide_unlock_order(UniqueWorker) end.to change { subject.unlock_order }.to :before_yield end end end describe '#before_yield?' do - it "returns unlock_order == :before_yield" do + it 'returns unlock_order == :before_yield' do allow(subject).to receive(:unlock_order).and_return(:after_yield) expect(subject.before_yield?).to eq(false) @@ -57,7 +57,7 @@ module Server end describe '#after_yield?' do - it "returns unlock_order == :before_yield" do + it 'returns unlock_order == :before_yield' do allow(subject).to receive(:unlock_order).and_return(:before_yield) expect(subject.after_yield?).to eq(false) @@ -68,14 +68,14 @@ module Server describe '#default_unlock_order' do it 'returns the default value from config' do - SidekiqUniqueJobs::Config.default_unlock_order = :before_yield + SidekiqUniqueJobs.config.default_unlock_order = :before_yield expect(subject.default_unlock_order).to eq(:before_yield) - SidekiqUniqueJobs::Config.default_unlock_order = :after_yield + SidekiqUniqueJobs.config.default_unlock_order = :after_yield expect(subject.default_unlock_order).to eq(:after_yield) end end end end end -end \ No newline at end of file +end diff --git a/spec/lib/sidekiq_testing_enabled_spec.rb b/spec/lib/sidekiq_testing_enabled_spec.rb index 77bb75f9f..265c35383 100644 --- a/spec/lib/sidekiq_testing_enabled_spec.rb +++ b/spec/lib/sidekiq_testing_enabled_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' require 'sidekiq/worker' -require "sidekiq-unique-jobs" +require 'sidekiq_unique_jobs' require 'sidekiq/scheduled' -require 'sidekiq-unique-jobs/middleware/server/unique_jobs' +require 'sidekiq_unique_jobs/middleware/server/unique_jobs' require 'rspec-sidekiq' -describe "When Sidekiq::Testing is enabled" do +describe 'When Sidekiq::Testing is enabled' do describe 'when set to :fake!', sidekiq: :fake do - context "with unique worker" do - it "does not push duplicate messages" do + context 'with unique worker' do + it 'does not push duplicate messages' do param = 'work' expect(UniqueWorker.jobs.size).to eq(0) UniqueWorker.perform_async(param) @@ -18,7 +18,7 @@ expect(UniqueWorker.jobs.size).to eq(1) end - it "adds the unique_hash to the message" do + it 'adds the unique_hash to the message' do param = 'hash' hash = SidekiqUniqueJobs::PayloadHelper.get_payload(UniqueWorker, :working, [param]) UniqueWorker.perform_async(param) @@ -27,9 +27,9 @@ end end - context "with non-unique worker" do + context 'with non-unique worker' do - it "pushes duplicates messages" do + it 'pushes duplicates messages' do param = 'work' expect(MyWorker.jobs.size).to eq(0) MyWorker.perform_async(param) @@ -44,7 +44,7 @@ describe 'when set to :inline!', sidekiq: :inline do class InlineWorker include Sidekiq::Worker - sidekiq_options :unique => true + sidekiq_options unique: true def perform(x) TestClass.run(x) @@ -53,7 +53,7 @@ def perform(x) class InlineUnlockOrderWorker include Sidekiq::Worker - sidekiq_options :unique => true, :unique_unlock_order => :never + sidekiq_options unique: true, unique_unlock_order: :never def perform(x) TestClass.run(x) @@ -61,7 +61,7 @@ def perform(x) end class TestClass - def self.run(x) + def self.run(_x) end end diff --git a/spec/lib/unlock_order_spec.rb b/spec/lib/unlock_order_spec.rb index f02e492c0..92c31317b 100644 --- a/spec/lib/unlock_order_spec.rb +++ b/spec/lib/unlock_order_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' require 'sidekiq/api' require 'sidekiq/worker' -require 'sidekiq-unique-jobs/middleware/server/unique_jobs' +require 'sidekiq_unique_jobs/middleware/server/unique_jobs' -describe "Unlock order" do +describe 'Unlock order' do QUEUE = 'unlock_ordering' class BeforeYieldOrderingWorker @@ -27,7 +27,7 @@ def perform describe 'with real redis' do before do Sidekiq.redis = REDIS - Sidekiq.redis { |c| c.flushdb } + Sidekiq.redis(&:flushdb) @middleware = SidekiqUniqueJobs::Middleware::Server::UniqueJobs.new end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c6a5edd66..6a1ff396f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,7 @@ -$TESTING = true - begin require 'pry' rescue LoadError + puts 'Pry unavailable' end require 'rspec' @@ -10,7 +9,7 @@ require 'celluloid/test' require 'sidekiq' require 'sidekiq/util' -require 'sidekiq-unique-jobs' +require 'sidekiq_unique_jobs' Sidekiq.logger.level = Logger::ERROR require 'rspec-sidekiq' @@ -19,10 +18,10 @@ require 'sidekiq/redis_connection' redis_url = ENV['REDIS_URL'] || 'redis://localhost/15' -REDIS = Sidekiq::RedisConnection.create(:url => redis_url, :namespace => 'testy') +REDIS = Sidekiq::RedisConnection.create(url: redis_url, namespace: 'testy') Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].each { |f| require f } -RSpec.configure do |config| +RSpec.configure do |_config| # config.treat_symbols_as_metadata_keys_with_true_values = true end @@ -35,4 +34,4 @@ # Warn when jobs are not enqueued to Redis but to a job array config.warn_when_jobs_not_processed_by_sidekiq = true # default => true -end \ No newline at end of file +end diff --git a/spec/support/my_worker.rb b/spec/support/my_worker.rb index 6a6c2c3d3..dbfba120d 100644 --- a/spec/support/my_worker.rb +++ b/spec/support/my_worker.rb @@ -1,7 +1,7 @@ class MyWorker include Sidekiq::Worker - sidekiq_options :queue => :working, :retry => 1, :backtrace => 10 - sidekiq_options :unique => false + sidekiq_options queue: :working, retry: 1, backtrace: 10 + sidekiq_options unique: false sidekiq_retries_exhausted do |msg| Sidekiq.logger.warn "Failed #{msg['class']} with #{msg['args']}: #{msg['error_message']}" @@ -10,4 +10,4 @@ class MyWorker def perform(param) puts param end -end \ No newline at end of file +end diff --git a/spec/support/sidekiq_meta.rb b/spec/support/sidekiq_meta.rb index 833713b46..a3de3e5b3 100644 --- a/spec/support/sidekiq_meta.rb +++ b/spec/support/sidekiq_meta.rb @@ -1,15 +1,12 @@ RSpec.configure do |config| config.before(:each) do |example| - sidekiq = example.metadata[:sidekiq] - if sidekiq + if (sidekiq = example.metadata[:sidekiq]) sidekiq = :fake if sidekiq == true Sidekiq::Testing.send("#{sidekiq}!") end end config.after(:each) do |example| - if sidekiq = example.metadata[:sidekiq] - Sidekiq::Testing.disable! - end + Sidekiq::Testing.disable! unless example.metadata[:sidekiq].nil? end -end \ No newline at end of file +end diff --git a/spec/support/unique_worker.rb b/spec/support/unique_worker.rb index 5e794d9df..2b504b711 100644 --- a/spec/support/unique_worker.rb +++ b/spec/support/unique_worker.rb @@ -1,7 +1,7 @@ class UniqueWorker include Sidekiq::Worker - sidekiq_options :queue => :working, :retry => 1, :backtrace => 10 - sidekiq_options :unique => true + sidekiq_options queue: :working, retry: 1, backtrace: 10 + sidekiq_options unique: true sidekiq_retries_exhausted do |msg| Sidekiq.logger.warn "Failed #{msg['class']} with #{msg['args']}: #{msg['error_message']}" @@ -10,4 +10,4 @@ class UniqueWorker def perform(param) puts param end -end \ No newline at end of file +end