diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5a0407a1e..ab8ce49c3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,8 +13,7 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: 3.1 - bundler: 2.4.12 + ruby-version: 3.2 bundler-cache: true - run: bin/bundle --jobs=$(nproc) --retry=$(nproc) - run: bin/rubocop -P diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index a9530339f..bea0a85d8 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -23,7 +23,6 @@ jobs: - uses: ruby/setup-ruby@v1 with: ruby-version: 3.2 - bundler: 2.4.12 bundler-cache: true - name: Install Code Climate reporter @@ -59,16 +58,17 @@ jobs: strategy: fail-fast: true matrix: - ruby: [2.7, '3.0', 3.1, 3.2] + ruby: ["2.7", '3.0', "3.1", "3.2", "3.3"] gemfile: - sidekiq_7.0 + - sidekiq_7.1 + - sidekiq_7.2 steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - bundler: 2.4.12 bundler-cache: true - run: >- REDIS_HOST=localhost diff --git a/.rubocop.yml b/.rubocop.yml index 7880245ef..1eea75746 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -34,6 +34,9 @@ Layout/EndAlignment: Layout/LineContinuationLeadingSpace: Enabled: false +Layout/MultilineMethodCallIndentation: + EnforcedStyle: indented + Lint/AmbiguousBlockAssociation: Exclude: - spec/**/* diff --git a/Appraisals b/Appraisals index 31df528e7..cc63395ab 100644 --- a/Appraisals +++ b/Appraisals @@ -7,3 +7,11 @@ appraise "sidekiq-7.0" do gem "sidekiq", "~> 7.0.0" end + +appraise "sidekiq-7.1" do + gem "sidekiq", "~> 7.1.0" +end + +appraise "sidekiq-7.2" do + gem "sidekiq", "~> 7.2.0" +end diff --git a/gemfiles/sidekiq_7.1.gemfile b/gemfiles/sidekiq_7.1.gemfile new file mode 100644 index 000000000..140999215 --- /dev/null +++ b/gemfiles/sidekiq_7.1.gemfile @@ -0,0 +1,28 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "faraday-retry" +gem "gem-release" +gem "github-markup" +gem "rack-test" +gem "rake", "13.0.3" +gem "reek", ">= 5.3" +gem "rspec" +gem "rspec-benchmark" +gem "rspec-html-matchers" +gem "rspec-its" +gem "rubocop-mhenrixon" +gem "simplecov-sublime", ">= 0.21.2", require: false +gem "sinatra" +gem "timecop" +gem "toxiproxy" +gem "yard" +gem "sidekiq", "~> 7.0.0" + +platforms :mri do + gem "concurrent-ruby-ext" +end + +gemspec path: "../" diff --git a/gemfiles/sidekiq_7.2.gemfile b/gemfiles/sidekiq_7.2.gemfile new file mode 100644 index 000000000..140999215 --- /dev/null +++ b/gemfiles/sidekiq_7.2.gemfile @@ -0,0 +1,28 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "faraday-retry" +gem "gem-release" +gem "github-markup" +gem "rack-test" +gem "rake", "13.0.3" +gem "reek", ">= 5.3" +gem "rspec" +gem "rspec-benchmark" +gem "rspec-html-matchers" +gem "rspec-its" +gem "rubocop-mhenrixon" +gem "simplecov-sublime", ">= 0.21.2", require: false +gem "sinatra" +gem "timecop" +gem "toxiproxy" +gem "yard" +gem "sidekiq", "~> 7.0.0" + +platforms :mri do + gem "concurrent-ruby-ext" +end + +gemspec path: "../" diff --git a/lib/sidekiq_unique_jobs/config.rb b/lib/sidekiq_unique_jobs/config.rb index bc625eae5..23192823c 100644 --- a/lib/sidekiq_unique_jobs/config.rb +++ b/lib/sidekiq_unique_jobs/config.rb @@ -67,10 +67,10 @@ class Config < ThreadSafeConfig # @return [Hash] + # @return [yield] call the rest of the middleware stack # - # @yieldparam [] if - # @yieldreturn [] + # @yieldparam [void] if uniquejobs is disable + # @yieldreturn [void] delegate back to other sidekiq middleware def call(worker_class, item, queue, redis_pool = nil) @item = item @queue = queue @@ -35,7 +35,7 @@ def call(worker_class, item, queue, redis_pool = nil) self.job_class = worker_class return yield if unique_disabled? - SidekiqUniqueJobs::Job.prepare(item) unless item[LOCK_DIGEST] + SidekiqUniqueJobs::Job.prepare(item) with_logging_context do super diff --git a/lib/sidekiq_unique_jobs/middleware/client.rb b/lib/sidekiq_unique_jobs/middleware/client.rb index 6fb9ed015..7c51c6af9 100644 --- a/lib/sidekiq_unique_jobs/middleware/client.rb +++ b/lib/sidekiq_unique_jobs/middleware/client.rb @@ -6,7 +6,7 @@ module Middleware # # @author Mikael Henriksson class Client - include Sidekiq::ClientMiddleware if defined?(Sidekiq::ClientMiddleware) + include Sidekiq::ClientMiddleware # prepend "SidekiqUniqueJobs::Middleware" # @!parse prepends SidekiqUniqueJobs::Middleware diff --git a/lib/sidekiq_unique_jobs/middleware/server.rb b/lib/sidekiq_unique_jobs/middleware/server.rb index fb7f1f525..b12311a03 100644 --- a/lib/sidekiq_unique_jobs/middleware/server.rb +++ b/lib/sidekiq_unique_jobs/middleware/server.rb @@ -6,7 +6,7 @@ module Middleware # # @author Mikael Henriksson class Server - include Sidekiq::ServerMiddleware if defined?(Sidekiq::ServerMiddleware) + include Sidekiq::ServerMiddleware # prepend "SidekiqUniqueJobs::Middleware" # @!parse prepends SidekiqUniqueJobs::Middleware diff --git a/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb b/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb index 9a3fd699b..b003592a8 100644 --- a/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +++ b/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb @@ -68,46 +68,24 @@ def delete(score, job_id) prepend UniqueExtension end - if Sidekiq.const_defined?(:JobRecord) - # See Sidekiq::Api - class JobRecord - # - # Provides extensions for unlocking jobs that are removed and deleted + # See Sidekiq::Api + class JobRecord + # + # Provides extensions for unlocking jobs that are removed and deleted + # + # @author Mikael Henriksson + # + module UniqueExtension # - # @author Mikael Henriksson + # Wraps the original method to ensure locks for the job are deleted # - module UniqueExtension - # - # Wraps the original method to ensure locks for the job are deleted - # - def delete - SidekiqUniqueJobs::Unlockable.delete!(item) - super - end + def delete + SidekiqUniqueJobs::Unlockable.delete!(item) + super end - - prepend UniqueExtension end - else - # See Sidekiq::Api - class Job - # - # Provides extensions for unlocking jobs that are removed and deleted - # - # @author Mikael Henriksson - # - module UniqueExtension - # - # Wraps the original method to ensure locks for the job are deleted - # - def delete - SidekiqUniqueJobs::Unlockable.delete!(item) - super - end - end - prepend UniqueExtension - end + prepend UniqueExtension end # See Sidekiq::Api diff --git a/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb b/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb index 7e1528d0a..3271f338b 100644 --- a/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb +++ b/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb @@ -250,9 +250,9 @@ def validate_worker!(options) # Attempt to constantize a string worker_class argument, always # failing back to the original argument when the constant can't be found # - # @return [Sidekiq::Worker] + # @return [Sidekiq::Job] def constantize(str) - return str.class if str.is_a?(Sidekiq::Worker) # sidekiq v6.x + return str.class if str.is_a?(Sidekiq::Job) # sidekiq v6.x return str unless str.is_a?(String) return Object.const_get(str) unless str.include?("::") @@ -269,7 +269,7 @@ def constantize(str) # Attempt to constantize a string worker_class argument, always # failing back to the original argument when the constant can't be found # - # @return [Sidekiq::Worker, String] + # @return [Sidekiq::Job, String] def safe_constantize(str) constantize(str) rescue NameError => ex diff --git a/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb b/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb index aa29c4c45..360110f4a 100644 --- a/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb +++ b/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true module SidekiqUniqueJobs - # Module with convenience methods for the Sidekiq::Worker class + # Module with convenience methods for the Sidekiq::Job class # # @author Mikael Henriksson module SidekiqWorkerMethods # # @!attribute [r] job_class - # @return [Sidekiq::Worker] The Sidekiq::Worker implementation + # @return [Sidekiq::Job] The Sidekiq::Job implementation attr_reader :job_class # Avoids duplicating worker_class.respond_to? in multiple places @@ -62,7 +62,7 @@ def after_unlock_hook # rubocop:disable Metrics/MethodLength # Attempt to constantize a string worker_class argument, always # failing back to the original argument when the constant can't be found # - # @return [Sidekiq::Worker] + # @return [Sidekiq::Job] def job_class_constantize(klazz = @job_class) SidekiqUniqueJobs.safe_constantize(klazz) end diff --git a/lib/sidekiq_unique_jobs/testing.rb b/lib/sidekiq_unique_jobs/testing.rb index be0fffba9..a195b5050 100644 --- a/lib/sidekiq_unique_jobs/testing.rb +++ b/lib/sidekiq_unique_jobs/testing.rb @@ -42,11 +42,11 @@ def self.use_options(tmp_config = {}) # rubocop:disable Metrics/MethodLength end # - # See Sidekiq::Worker in Sidekiq gem for more details + # See Sidekiq::Job in Sidekiq gem for more details # module Worker # - # Adds class methods to Sidekiq::Worker + # Adds class methods to Sidekiq::Job # module ClassMethods # @@ -110,14 +110,14 @@ def clear prepend Overrides # - # Prepends methods to Sidekiq::Worker + # Prepends methods to Sidekiq::Job # module ClassMethods prepend Overrides::ClassMethods end # - # Prepends singleton methods to Sidekiq::Worker + # Prepends singleton methods to Sidekiq::Job # module SignletonOverrides # diff --git a/lib/sidekiq_unique_jobs/web/helpers.rb b/lib/sidekiq_unique_jobs/web/helpers.rb index 0cb27403a..26696b30b 100644 --- a/lib/sidekiq_unique_jobs/web/helpers.rb +++ b/lib/sidekiq_unique_jobs/web/helpers.rb @@ -133,7 +133,7 @@ def redirect_to(subpath) # # @return [String] a html safe string with relative time information # - def relative_time(time) + def _relative_time(time) stamp = time.getutc.iso8601 %() end @@ -145,12 +145,12 @@ def relative_time(time) # # @return [String] a html safe string with relative time information # - def safe_relative_time(time) + def _safe_relative_time(time) return unless time time = parse_time(time) - relative_time(time) + _relative_time(time) end # diff --git a/lib/sidekiq_unique_jobs/web/views/changelogs.erb b/lib/sidekiq_unique_jobs/web/views/changelogs.erb index fe0e7009f..b4a0f5f9b 100644 --- a/lib/sidekiq_unique_jobs/web/views/changelogs.erb +++ b/lib/sidekiq_unique_jobs/web/views/changelogs.erb @@ -42,7 +42,7 @@ <% @changelogs.each do |changelog| %> - <%= safe_relative_time(changelog['time']) || "bogus" %> + <%= _safe_relative_time(changelog['time']) || "bogus" %> <%= changelog["digest"] %> <%= changelog["script"] %> <%= changelog["job_id"] %> diff --git a/lib/sidekiq_unique_jobs/web/views/lock.erb b/lib/sidekiq_unique_jobs/web/views/lock.erb index f8beba3b4..bce46d0d3 100644 --- a/lib/sidekiq_unique_jobs/web/views/lock.erb +++ b/lib/sidekiq_unique_jobs/web/views/lock.erb @@ -65,7 +65,7 @@ <% @lock.locked_jids(with_values: true).each do |job_id, time| %> <%= job_id %> - <%= safe_relative_time(time.to_f) %> + <%= _safe_relative_time(time.to_f) %>
<%= csrf_tag %> @@ -92,7 +92,7 @@ <% @lock.changelogs.each do |entry| %> - <%= safe_relative_time(entry["time"].to_f) %> + <%= _safe_relative_time(entry["time"].to_f) %> <%= entry["job_id"] %> <%= entry["message"] %> <%= entry["script"] %> diff --git a/lib/sidekiq_unique_jobs/web/views/locks.erb b/lib/sidekiq_unique_jobs/web/views/locks.erb index d53d97703..ed04dd577 100644 --- a/lib/sidekiq_unique_jobs/web/views/locks.erb +++ b/lib/sidekiq_unique_jobs/web/views/locks.erb @@ -46,7 +46,7 @@ <%= lock.key %> <%= lock.info["lock"] %> <%= lock.locked.count %> - <%= safe_relative_time(lock.created_at) %> + <%= _safe_relative_time(lock.created_at) %> <% end %> diff --git a/spec/jobs/another_unique_job_job_spec.rb b/spec/jobs/another_unique_job_job_spec.rb index fb3eddc47..000b34c83 100644 --- a/spec/jobs/another_unique_job_job_spec.rb +++ b/spec/jobs/another_unique_job_job_spec.rb @@ -1,20 +1,18 @@ # frozen_string_literal: true -if Sidekiq.const_defined?(:JobRecord) - RSpec.describe AnotherUniqueJobJob do - it_behaves_like "sidekiq with options" do - let(:options) do - { - "queue" => :working2, - "retry" => 1, - "backtrace" => 10, - "lock" => :until_executed, - } - end +RSpec.describe AnotherUniqueJobJob do + it_behaves_like "sidekiq with options" do + let(:options) do + { + "queue" => :working2, + "retry" => 1, + "backtrace" => 10, + "lock" => :until_executed, + } end + end - it_behaves_like "a performing worker", splat_arguments: false do - let(:args) { %w[one two] } - end + it_behaves_like "a performing worker", splat_arguments: false do + let(:args) { %w[one two] } end end diff --git a/spec/sidekiq/api_spec.rb b/spec/sidekiq/api_spec.rb index 082ac159a..8d402eb04 100644 --- a/spec/sidekiq/api_spec.rb +++ b/spec/sidekiq/api_spec.rb @@ -49,23 +49,12 @@ end end - if Sidekiq.const_defined?(:JobRecord) - describe Sidekiq::JobRecord::UniqueExtension do - it "deletes uniqueness lock on delete" do - jid = JustAWorker.perform_async("roo" => "baf") - expect(unique_keys).not_to eq([]) - Sidekiq::Queue.new("testqueue").find_job(jid).delete - expect(unique_keys).to eq([]) - end - end - else - describe Sidekiq::Job::UniqueExtension do - it "deletes uniqueness lock on delete" do - jid = JustAWorker.perform_async("roo" => "baf") - expect(unique_keys).not_to eq([]) - Sidekiq::Queue.new("testqueue").find_job(jid).delete - expect(unique_keys).to eq([]) - end + describe Sidekiq::JobRecord::UniqueExtension do + it "deletes uniqueness lock on delete" do + jid = JustAWorker.perform_async("roo" => "baf") + expect(unique_keys).not_to eq([]) + Sidekiq::Queue.new("testqueue").find_job(jid).delete + expect(unique_keys).to eq([]) end end diff --git a/spec/sidekiq/worker_spec.rb b/spec/sidekiq/job_spec.rb similarity index 78% rename from spec/sidekiq/worker_spec.rb rename to spec/sidekiq/job_spec.rb index 1156716cf..06539b206 100644 --- a/spec/sidekiq/worker_spec.rb +++ b/spec/sidekiq/job_spec.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -RSpec.describe "Sidekiq::Worker" do +RSpec.describe Sidekiq::Job do describe "#clear_all" do it "unlocks all unique locks" do expect(UntilAndWhileExecutingJob.perform_async).not_to be_nil - Sidekiq::Worker.clear_all + described_class.clear_all expect(UntilAndWhileExecutingJob.perform_async).not_to be_nil end end diff --git a/spec/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 65625c5f0..87e962734 100644 --- a/spec/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -27,11 +27,7 @@ let(:lock_timeout) { nil } let(:sleepy_time) { 0 } - if Sidekiq.const_defined?(:JobRecord) - let(:job_class) { AnotherUniqueJobJob } - else - let(:job_class) { UntilAndWhileExecutingJob } - end + let(:job_class) { AnotherUniqueJobJob } before do allow(runtime_one).to receive(:reflect).and_call_original diff --git a/spec/sidekiq_unique_jobs/lua/unlock_spec.rb b/spec/sidekiq_unique_jobs/lua/unlock_spec.rb index cb749edd6..9e82e98eb 100644 --- a/spec/sidekiq_unique_jobs/lua/unlock_spec.rb +++ b/spec/sidekiq_unique_jobs/lua/unlock_spec.rb @@ -184,7 +184,7 @@ context "with same job_id", :with_a_lock do it "does unlock" do expect { unlock }.to change { changelogs.count }.by(1) - .and change { digests.count }.by(-1) + .and change { digests.count }.by(-1) expect(queued.count).to eq(1) expect(queued.entries).to contain_exactly("1") diff --git a/spec/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options_spec.rb b/spec/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options_spec.rb index 5996309fa..21bac97c4 100644 --- a/spec/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options_spec.rb +++ b/spec/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options_spec.rb @@ -2,30 +2,6 @@ RSpec.describe SidekiqUniqueJobs::RSpec::Matchers::HaveValidSidekiqOptions do describe "#matches?" do - if Sidekiq.const_defined?(:JobRecord) - context "when sidekiq options are valid" do - it { expect(AnotherUniqueJob).to have_valid_sidekiq_options } - end - - context "when sidekiq options lacks `:lock`" do - it "raises SidekiqUniqueJobs::NotUniqueWorker" do - AnotherUniqueJob.use_options({}) do - AnotherUniqueJob.sidekiq_options_hash.delete("lock") - expect { expect(AnotherUniqueJob).to have_valid_sidekiq_options } - .to raise_error(SidekiqUniqueJobs::NotUniqueWorker) - end - end - end - - context "when sidekiq options are invalid" do - it "raises SidekiqUniqueJobs::NotUniqueWorker" do - AnotherUniqueJob.use_options(on_client_conflict: :reject, on_server_conflict: :replace) do - expect(AnotherUniqueJob).not_to have_valid_sidekiq_options - end - end - end - end - context "when sidekiq options are valid" do it { expect(AnotherUniqueJob).to have_valid_sidekiq_options } end @@ -48,4 +24,26 @@ end end end + + context "when sidekiq options are valid" do + it { expect(AnotherUniqueJob).to have_valid_sidekiq_options } + end + + context "when sidekiq options lacks `:lock`" do + it "raises SidekiqUniqueJobs::NotUniqueWorker" do + AnotherUniqueJob.use_options({}) do + AnotherUniqueJob.sidekiq_options_hash.delete("lock") + expect { expect(AnotherUniqueJob).to have_valid_sidekiq_options } + .to raise_error(SidekiqUniqueJobs::NotUniqueWorker) + end + end + end + + context "when sidekiq options are invalid" do + it "raises SidekiqUniqueJobs::NotUniqueWorker" do + AnotherUniqueJob.use_options(on_client_conflict: :reject, on_server_conflict: :replace) do + expect(AnotherUniqueJob).not_to have_valid_sidekiq_options + end + end + end end diff --git a/spec/sidekiq_unique_jobs/web/helpers_spec.rb b/spec/sidekiq_unique_jobs/web/helpers_spec.rb index 84bc17429..003317aab 100644 --- a/spec/sidekiq_unique_jobs/web/helpers_spec.rb +++ b/spec/sidekiq_unique_jobs/web/helpers_spec.rb @@ -19,8 +19,8 @@ def params let(:helper) { SidekiqUniqueJobs::WebHelpers.new } - describe "#safe_relative_time" do - subject(:safe_relative_time) { helper.safe_relative_time(time) } + describe "#_safe_relative_time" do + subject(:safe_relative_time) { helper._safe_relative_time(time) } let(:frozen_time) { Time.new(1982, 6, 8, 14, 15, 34) } let(:time) { Time.now.to_f } diff --git a/spec/support/jobs/another_unique_job_job.rb b/spec/support/jobs/another_unique_job_job.rb index f85ea3184..ee155d441 100644 --- a/spec/support/jobs/another_unique_job_job.rb +++ b/spec/support/jobs/another_unique_job_job.rb @@ -1,18 +1,16 @@ # frozen_string_literal: true # :nocov: -if Sidekiq.const_defined?(:JobRecord) - require "sidekiq/job" +require "sidekiq/job" - class AnotherUniqueJobJob - include Sidekiq::Job - sidekiq_options backtrace: 10, - lock: :until_executed, - queue: :working2, - retry: 1 +class AnotherUniqueJobJob + include Sidekiq::Job + sidekiq_options backtrace: 10, + lock: :until_executed, + queue: :working2, + retry: 1 - def perform(args) - args - end + def perform(args) + args end end diff --git a/spec/support/workers/another_unique_job.rb b/spec/support/workers/another_unique_job.rb index 64f4a44a9..45e85497c 100644 --- a/spec/support/workers/another_unique_job.rb +++ b/spec/support/workers/another_unique_job.rb @@ -3,7 +3,7 @@ # :nocov: class AnotherUniqueJob - include Sidekiq::Worker + include Sidekiq::Job sidekiq_options backtrace: 10, lock: :until_executed, queue: :working2, diff --git a/spec/support/workers/simple_worker.rb b/spec/support/workers/simple_worker.rb index cd32608e2..baaf6b084 100644 --- a/spec/support/workers/simple_worker.rb +++ b/spec/support/workers/simple_worker.rb @@ -5,7 +5,8 @@ class SimpleWorker include Sidekiq::Worker - sidekiq_options lock: :until_executed, + sidekiq_options backtrace: true, + lock: :until_executed, queue: :default, lock_args_method: ->(args) { [args.first] } diff --git a/spec/support/workers/without_argument_job.rb b/spec/support/workers/without_argument_job.rb index 6cd0f1b41..22d0b5b1b 100644 --- a/spec/support/workers/without_argument_job.rb +++ b/spec/support/workers/without_argument_job.rb @@ -3,7 +3,7 @@ # :nocov: class WithoutArgumentJob - include Sidekiq::Worker + include Sidekiq::Job sidekiq_options lock: :until_executed def perform