diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d9a4b5c..45bae5a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,10 @@ name: Main -on: [push,pull_request,workflow_dispatch] +on: + push: + branches: [main] + pull_request: + workflow_dispatch: jobs: build: @@ -20,12 +24,12 @@ jobs: strategy: matrix: ruby: - - 2.5.9 - - 2.6.10 - - 2.7.7 - - 3.0.5 - - 3.1.3 - - 3.2.0 + - 2.7.8 + - 3.0.7 + - 3.1.7 + - 3.2.9 + - 3.3.9 + - 3.4.7 gemfile: - gemfiles/activejob_4.2.x.gemfile - gemfiles/activejob_5.2.x.gemfile @@ -35,78 +39,91 @@ jobs: - gemfiles/activejob_7.1.x.gemfile - gemfiles/activejob_7.2.x.gemfile - gemfiles/activejob_8.0.x.gemfile + - gemfiles/activejob_8.1.x.gemfile - gemfiles/sidekiq_4.x.gemfile - gemfiles/sidekiq_5.x.gemfile - gemfiles/sidekiq_6.x.gemfile - gemfiles/sidekiq_7.x.gemfile exclude: - - ruby: 2.5.9 - gemfile: gemfiles/activejob_7.0.x.gemfile - - ruby: 2.5.9 - gemfile: gemfiles/activejob_7.1.x.gemfile - - ruby: 2.5.9 - gemfile: gemfiles/activejob_7.2.x.gemfile - - ruby: 2.5.9 - gemfile: gemfiles/activejob_8.0.x.gemfile - - ruby: 2.5.9 - gemfile: gemfiles/sidekiq_6.x.gemfile - - ruby: 2.5.9 - gemfile: gemfiles/sidekiq_7.x.gemfile - - ruby: 2.6.10 - gemfile: gemfiles/activejob_7.0.x.gemfile - - ruby: 2.6.10 - gemfile: gemfiles/activejob_7.1.x.gemfile - - ruby: 2.6.10 - gemfile: gemfiles/activejob_7.2.x.gemfile - - ruby: 2.6.10 - gemfile: gemfiles/activejob_8.0.x.gemfile - - ruby: 2.6.10 - gemfile: gemfiles/sidekiq_6.x.gemfile - - ruby: 2.6.10 - gemfile: gemfiles/sidekiq_7.x.gemfile - - ruby: 2.7.7 + - ruby: 2.7.8 gemfile: gemfiles/activejob_4.2.x.gemfile - - ruby: 2.7.7 + - ruby: 2.7.8 gemfile: gemfiles/activejob_7.2.x.gemfile - - ruby: 2.7.7 + - ruby: 2.7.8 gemfile: gemfiles/activejob_8.0.x.gemfile - - ruby: 2.7.7 + - ruby: 2.7.8 + gemfile: gemfiles/activejob_8.1.x.gemfile + - ruby: 2.7.8 gemfile: gemfiles/sidekiq_4.x.gemfile - - ruby: 3.0.5 + - ruby: 2.7.8 + gemfile: gemfiles/sidekiq_8.x.gemfile + - ruby: 3.0.7 gemfile: gemfiles/activejob_4.2.x.gemfile - - ruby: 3.0.5 + - ruby: 3.0.7 gemfile: gemfiles/activejob_5.2.x.gemfile - - ruby: 3.0.5 + - ruby: 3.0.7 gemfile: gemfiles/activejob_7.2.x.gemfile - - ruby: 3.0.5 + - ruby: 3.0.7 gemfile: gemfiles/activejob_8.0.x.gemfile - - ruby: 3.0.5 + - ruby: 3.0.7 + gemfile: gemfiles/activejob_8.1.x.gemfile + - ruby: 3.0.7 gemfile: gemfiles/sidekiq_4.x.gemfile - - ruby: 3.0.5 + - ruby: 3.0.7 gemfile: gemfiles/sidekiq_5.x.gemfile - - ruby: 3.1.3 + - ruby: 3.0.7 + gemfile: gemfiles/sidekiq_8.x.gemfile + - ruby: 3.1.7 gemfile: gemfiles/activejob_4.2.x.gemfile - - ruby: 3.1.3 + - ruby: 3.1.7 gemfile: gemfiles/activejob_5.2.x.gemfile - - ruby: 3.1.3 + - ruby: 3.1.7 gemfile: gemfiles/activejob_6.0.x.gemfile - - ruby: 3.1.3 + - ruby: 3.1.7 gemfile: gemfiles/activejob_8.0.x.gemfile - - ruby: 3.1.3 + - ruby: 3.1.7 + gemfile: gemfiles/activejob_8.1.x.gemfile + - ruby: 3.1.7 + gemfile: gemfiles/sidekiq_4.x.gemfile + - ruby: 3.1.7 + gemfile: gemfiles/sidekiq_5.x.gemfile + - ruby: 3.1.7 + gemfile: gemfiles/sidekiq_8.x.gemfile + - ruby: 3.2.9 + gemfile: gemfiles/activejob_4.2.x.gemfile + - ruby: 3.2.9 + gemfile: gemfiles/activejob_5.2.x.gemfile + - ruby: 3.2.9 + gemfile: gemfiles/activejob_6.0.x.gemfile + - ruby: 3.2.9 + gemfile: gemfiles/activejob_7.1.x.gemfile + - ruby: 3.2.9 + gemfile: gemfiles/sidekiq_4.x.gemfile + - ruby: 3.2.9 + gemfile: gemfiles/sidekiq_5.x.gemfile + - ruby: 3.3.9 + gemfile: gemfiles/activejob_4.2.x.gemfile + - ruby: 3.3.9 + gemfile: gemfiles/activejob_5.2.x.gemfile + - ruby: 3.3.9 + gemfile: gemfiles/activejob_6.0.x.gemfile + - ruby: 3.3.9 + gemfile: gemfiles/activejob_7.1.x.gemfile + - ruby: 3.3.9 gemfile: gemfiles/sidekiq_4.x.gemfile - - ruby: 3.1.3 + - ruby: 3.3.9 gemfile: gemfiles/sidekiq_5.x.gemfile - - ruby: 3.2.0 + - ruby: 3.4.7 gemfile: gemfiles/activejob_4.2.x.gemfile - - ruby: 3.2.0 + - ruby: 3.4.7 gemfile: gemfiles/activejob_5.2.x.gemfile - - ruby: 3.2.0 + - ruby: 3.4.7 gemfile: gemfiles/activejob_6.0.x.gemfile - - ruby: 3.2.0 + - ruby: 3.4.7 gemfile: gemfiles/activejob_7.1.x.gemfile - - ruby: 3.2.0 + - ruby: 3.4.7 gemfile: gemfiles/sidekiq_4.x.gemfile - - ruby: 3.2.0 + - ruby: 3.3.9 gemfile: gemfiles/sidekiq_5.x.gemfile steps: diff --git a/.rubocop.yml b/.rubocop.yml index 12ed9b1..4b841f3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,8 @@ -require: rubocop-rspec +plugins: + - rubocop-rspec AllCops: - TargetRubyVersion: 2.5 + TargetRubyVersion: 2.7 NewCops: enable Exclude: - gemfiles/**/* @@ -66,3 +67,12 @@ RSpec/AnyInstance: RSpec/LetSetup: Exclude: - spec/active_job/uniqueness/sidekiq_patch_spec.rb + +RSpec/IncludeExamples: + Enabled: false + +Naming/PredicateMethod: + Enabled: false + +Lint/FloatComparison: + Enabled: false diff --git a/Appraisals b/Appraisals index da90931..699b686 100644 --- a/Appraisals +++ b/Appraisals @@ -9,15 +9,15 @@ appraise 'activejob-5.2.x' do end appraise 'activejob-6.0.x' do - gem 'activejob', '~> 6.0.5' + gem 'activejob', '~> 6.0.6' end appraise 'activejob-6.1.x' do - gem 'activejob', '~> 6.1.6' + gem 'activejob', '~> 6.1.7' end appraise 'activejob-7.0.x' do - gem 'activejob', '~> 7.0.3' + gem 'activejob', '~> 7.0.8' end appraise 'activejob-7.1.x' do @@ -32,6 +32,10 @@ appraise 'activejob-8.0.x' do gem 'activejob', '>= 8.0.0.rc1', '< 8.1' end +appraise 'activejob-8.1.x' do + gem 'activejob', '>= 8.1.0.rc1', '< 8.2' +end + appraise 'sidekiq-4.x' do gem 'sidekiq', '~> 4.2' gem 'activejob', '~> 5.2' @@ -47,5 +51,5 @@ appraise 'sidekiq-6.x' do end appraise 'sidekiq-7.x' do - gem 'sidekiq', '~> 7.0' + gem 'sidekiq', '~> 7.3' end diff --git a/CHANGELOG.md b/CHANGELOG.md index 31d6fdd..8f44395 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased](https://github.com/veeqo/activejob-uniqueness/compare/v0.4.0...HEAD) +- [#91](https://github.com/veeqo/activejob-uniqueness/pull/91) Add ActiveJob 8.1 support by [@viralpraxis](https://github.com/viralpraxis) ## [0.4.0](https://github.com/veeqo/activejob-uniqueness/compare/v0.3.2...v0.4.0) - 2024-12-07 diff --git a/activejob-uniqueness.gemspec b/activejob-uniqueness.gemspec index 6e1c35a..69f52c7 100644 --- a/activejob-uniqueness.gemspec +++ b/activejob-uniqueness.gemspec @@ -28,13 +28,20 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 2.5' - spec.add_dependency 'activejob', '>= 4.2', '< 8.1' + spec.add_dependency 'activejob', '>= 4.2', '< 8.2' + spec.add_dependency 'activesupport', '>= 4.2', '< 8.2' spec.add_dependency 'redlock', '>= 2.0', '< 3' + spec.add_development_dependency 'mutex_m' + spec.add_development_dependency 'bigdecimal' + spec.add_development_dependency 'logger' + spec.add_development_dependency 'base64' spec.add_development_dependency 'appraisal', '~> 2.3.0' spec.add_development_dependency 'bundler', '>= 2.0' spec.add_development_dependency 'pry-byebug', '> 3.6.0' spec.add_development_dependency 'rspec', '~> 3.0' spec.add_development_dependency 'rubocop', '~> 1.28' - spec.add_development_dependency 'rubocop-rspec', '~> 2.10' + spec.add_development_dependency 'rubocop-rspec', '~> 3.7' + spec.add_development_dependency 'readline' + spec.add_development_dependency 'irb' end diff --git a/gemfiles/activejob_6.0.x.gemfile b/gemfiles/activejob_6.0.x.gemfile index 7b671fa..6778133 100644 --- a/gemfiles/activejob_6.0.x.gemfile +++ b/gemfiles/activejob_6.0.x.gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -gem "activejob", "~> 6.0.5" +gem "activejob", "~> 6.0.6" gemspec path: "../" diff --git a/gemfiles/activejob_6.1.x.gemfile b/gemfiles/activejob_6.1.x.gemfile index 13ddff7..58a1d5f 100644 --- a/gemfiles/activejob_6.1.x.gemfile +++ b/gemfiles/activejob_6.1.x.gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -gem "activejob", "~> 6.1.6" +gem "activejob", "~> 6.1.7" gemspec path: "../" diff --git a/gemfiles/activejob_7.0.x.gemfile b/gemfiles/activejob_7.0.x.gemfile index 014c658..bc33c70 100644 --- a/gemfiles/activejob_7.0.x.gemfile +++ b/gemfiles/activejob_7.0.x.gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -gem "activejob", "~> 7.0.3" +gem "activejob", "~> 7.0.8" gemspec path: "../" diff --git a/gemfiles/activejob_8.1.x.gemfile b/gemfiles/activejob_8.1.x.gemfile new file mode 100644 index 0000000..4a5f960 --- /dev/null +++ b/gemfiles/activejob_8.1.x.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activejob", ">= 8.1.0.rc1", "< 8.2" + +gemspec path: "../" diff --git a/gemfiles/sidekiq_7.x.gemfile b/gemfiles/sidekiq_7.x.gemfile index efa4846..abf23af 100644 --- a/gemfiles/sidekiq_7.x.gemfile +++ b/gemfiles/sidekiq_7.x.gemfile @@ -2,6 +2,6 @@ source "https://rubygems.org" -gem "sidekiq", "~> 7.0" +gem "sidekiq", "~> 7.0", "!= 7.3.9" gemspec path: "../" diff --git a/lib/active_job/uniqueness.rb b/lib/active_job/uniqueness.rb index 286bfb6..a0ad6d1 100644 --- a/lib/active_job/uniqueness.rb +++ b/lib/active_job/uniqueness.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'logger' + require 'active_job' require 'redlock' diff --git a/lib/active_job/uniqueness/configuration.rb b/lib/active_job/uniqueness/configuration.rb index 357b92d..a78a780 100644 --- a/lib/active_job/uniqueness/configuration.rb +++ b/lib/active_job/uniqueness/configuration.rb @@ -1,52 +1,54 @@ # frozen_string_literal: true +require 'openssl' + module ActiveJob module Uniqueness - # Use /config/initializer/activejob_uniqueness.rb to configure ActiveJob::Uniqueness + # Use config/initializer/activejob_uniqueness.rb to configure ActiveJob::Uniqueness # # ActiveJob::Uniqueness.configure do |c| # c.lock_ttl = 3.hours # end # class Configuration - include ActiveSupport::Configurable - - config_accessor(:lock_ttl) { 86_400 } # 1.day - config_accessor(:lock_prefix) { 'activejob_uniqueness' } - config_accessor(:on_conflict) { :raise } - config_accessor(:on_redis_connection_error) { :raise } - config_accessor(:redlock_servers) { [ENV.fetch('REDIS_URL', 'redis://localhost:6379')] } - config_accessor(:redlock_options) { { retry_count: 0 } } - config_accessor(:lock_strategies) { {} } - - config_accessor(:digest_method) do - require 'openssl' - OpenSSL::Digest::MD5 - end + module Validations + def on_conflict=(action) + validate_on_conflict_action!(action) - def on_conflict=(action) - validate_on_conflict_action!(action) + super + end - config.on_conflict = action - end + def validate_on_conflict_action!(action) + return if action.nil? || %i[log raise].include?(action) || action.respond_to?(:call) - def validate_on_conflict_action!(action) - return if action.nil? || %i[log raise].include?(action) || action.respond_to?(:call) + raise ActiveJob::Uniqueness::InvalidOnConflictAction, "Unexpected '#{action}' action on conflict" + end - raise ActiveJob::Uniqueness::InvalidOnConflictAction, "Unexpected '#{action}' action on conflict" - end + def on_redis_connection_error=(action) + validate_on_redis_connection_error!(action) - def on_redis_connection_error=(action) - validate_on_redis_connection_error!(action) + super + end - config.on_redis_connection_error = action + def validate_on_redis_connection_error!(action) + return if action.nil? || action == :raise || action.respond_to?(:call) + + raise ActiveJob::Uniqueness::InvalidOnConflictAction, + "Unexpected '#{action}' action on_redis_connection_error" + end end - def validate_on_redis_connection_error!(action) - return if action.nil? || action == :raise || action.respond_to?(:call) + class_attribute :lock_ttl, default: 86_400 + class_attribute :lock_prefix, default: 'activejob_uniqueness' + class_attribute :on_conflict, default: :raise + class_attribute :on_redis_connection_error, default: :raise + class_attribute :redlock_servers, default: [ENV.fetch('REDIS_URL', 'redis://localhost:6379')] + class_attribute :redlock_options, default: { retry_count: 0 } + class_attribute :lock_strategies, default: {} - raise ActiveJob::Uniqueness::InvalidOnConflictAction, "Unexpected '#{action}' action on_redis_connection_error" - end + class_attribute :digest_method, default: OpenSSL::Digest::MD5 + + prepend Validations end end end