activejob-uniqueness 0.1.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +115 -10
- data/README.md +140 -14
- data/lib/active_job/uniqueness/{patch.rb → active_job_patch.rb} +10 -12
- data/lib/active_job/uniqueness/configuration.rb +20 -3
- data/lib/active_job/uniqueness/lock_key.rb +9 -1
- data/lib/active_job/uniqueness/lock_manager.rb +20 -4
- data/lib/active_job/uniqueness/log_subscriber.rb +68 -67
- data/lib/active_job/uniqueness/sidekiq_patch.rb +98 -0
- data/lib/active_job/uniqueness/strategies/base.rb +20 -5
- data/lib/active_job/uniqueness/strategies/until_and_while_executing.rb +9 -9
- data/lib/active_job/uniqueness/version.rb +1 -1
- data/lib/active_job/uniqueness.rb +9 -6
- data/lib/generators/active_job/uniqueness/templates/config/initializers/active_job_uniqueness.rb +11 -4
- metadata +59 -31
- data/.gitignore +0 -14
- data/.rspec +0 -3
- data/.rubocop.yml +0 -38
- data/.travis.yml +0 -22
- data/Gemfile +0 -15
- data/Rakefile +0 -8
- data/activejob-uniqueness.gemspec +0 -36
- data/lib/active_job/uniqueness/patch/sidekiq.rb +0 -93
|
@@ -3,99 +3,100 @@
|
|
|
3
3
|
require 'active_support/log_subscriber'
|
|
4
4
|
|
|
5
5
|
module ActiveJob
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
module Uniqueness
|
|
7
|
+
class LogSubscriber < ActiveSupport::LogSubscriber # :nodoc:
|
|
8
|
+
def lock(event)
|
|
9
|
+
job = event.payload[:job]
|
|
10
|
+
resource = event.payload[:resource]
|
|
11
|
+
|
|
12
|
+
debug do
|
|
13
|
+
"Locked #{lock_info(job, resource)}" + args_info(job)
|
|
14
|
+
end
|
|
13
15
|
end
|
|
14
|
-
end
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
def runtime_lock(event)
|
|
18
|
+
job = event.payload[:job]
|
|
19
|
+
resource = event.payload[:resource]
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
debug do
|
|
22
|
+
"Locked runtime #{lock_info(job, resource)}" + args_info(job)
|
|
23
|
+
end
|
|
22
24
|
end
|
|
23
|
-
end
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
def unlock(event)
|
|
27
|
+
job = event.payload[:job]
|
|
28
|
+
resource = event.payload[:resource]
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
debug do
|
|
31
|
+
"Unlocked #{lock_info(job, resource)}"
|
|
32
|
+
end
|
|
31
33
|
end
|
|
32
|
-
end
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
def runtime_unlock(event)
|
|
36
|
+
job = event.payload[:job]
|
|
37
|
+
resource = event.payload[:resource]
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
debug do
|
|
40
|
+
"Unlocked runtime #{lock_info(job, resource)}"
|
|
41
|
+
end
|
|
40
42
|
end
|
|
41
|
-
end
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
def conflict(event)
|
|
45
|
+
job = event.payload[:job]
|
|
46
|
+
resource = event.payload[:resource]
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
info do
|
|
49
|
+
"Not unique #{lock_info(job, resource)}" + args_info(job)
|
|
50
|
+
end
|
|
49
51
|
end
|
|
50
|
-
end
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
def runtime_conflict(event)
|
|
54
|
+
job = event.payload[:job]
|
|
55
|
+
resource = event.payload[:resource]
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
info do
|
|
58
|
+
"Not unique runtime #{lock_info(job, resource)}" + args_info(job)
|
|
59
|
+
end
|
|
58
60
|
end
|
|
59
|
-
end
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
private
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
def lock_info(job, resource)
|
|
65
|
+
"#{job.class.name} (Job ID: #{job.job_id}) (Lock key: #{resource})"
|
|
66
|
+
end
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
def args_info(job)
|
|
69
|
+
if job.arguments.any? && log_arguments?(job)
|
|
70
|
+
" with arguments: #{job.arguments.map { |arg| format(arg).inspect }.join(', ')}"
|
|
71
|
+
else
|
|
72
|
+
''
|
|
73
|
+
end
|
|
73
74
|
end
|
|
74
|
-
end
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
def log_arguments?(job)
|
|
77
|
+
return true unless job.class.respond_to?(:log_arguments?)
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
job.class.log_arguments?
|
|
80
|
+
end
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
def format(arg)
|
|
83
|
+
case arg
|
|
84
|
+
when Hash
|
|
85
|
+
arg.transform_values { |value| format(value) }
|
|
86
|
+
when Array
|
|
87
|
+
arg.map { |value| format(value) }
|
|
88
|
+
when GlobalID::Identification
|
|
89
|
+
arg.to_global_id rescue arg
|
|
90
|
+
else
|
|
91
|
+
arg
|
|
92
|
+
end
|
|
92
93
|
end
|
|
93
|
-
end
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
def logger
|
|
96
|
+
ActiveJob::Base.logger
|
|
97
|
+
end
|
|
97
98
|
end
|
|
98
99
|
end
|
|
99
100
|
end
|
|
100
101
|
|
|
101
|
-
ActiveJob::LogSubscriber.attach_to :active_job_uniqueness
|
|
102
|
+
ActiveJob::Uniqueness::LogSubscriber.attach_to :active_job_uniqueness
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'activejob/uniqueness'
|
|
4
|
+
require 'sidekiq/api'
|
|
5
|
+
|
|
6
|
+
module ActiveJob
|
|
7
|
+
module Uniqueness
|
|
8
|
+
def self.unlock_sidekiq_job!(job_data)
|
|
9
|
+
return unless job_data['class'] == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' # non ActiveJob jobs
|
|
10
|
+
|
|
11
|
+
job = ActiveJob::Base.deserialize(job_data.fetch('args').first)
|
|
12
|
+
|
|
13
|
+
return unless job.class.lock_strategy_class
|
|
14
|
+
|
|
15
|
+
begin
|
|
16
|
+
job.send(:deserialize_arguments_if_needed)
|
|
17
|
+
rescue ActiveJob::DeserializationError
|
|
18
|
+
# Most probably, GlobalID fails to locate AR record (record is deleted)
|
|
19
|
+
else
|
|
20
|
+
ActiveJob::Uniqueness.unlock!(job_class_name: job.class.name, arguments: job.arguments)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module SidekiqPatch
|
|
25
|
+
module SortedEntry
|
|
26
|
+
def delete
|
|
27
|
+
ActiveJob::Uniqueness.unlock_sidekiq_job!(item) if super
|
|
28
|
+
item
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def remove_job
|
|
34
|
+
super do |message|
|
|
35
|
+
ActiveJob::Uniqueness.unlock_sidekiq_job!(Sidekiq.load_json(message))
|
|
36
|
+
yield message
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module ScheduledSet
|
|
42
|
+
def delete(score, job_id)
|
|
43
|
+
entry = find_job(job_id)
|
|
44
|
+
ActiveJob::Uniqueness.unlock_sidekiq_job!(entry.item) if super
|
|
45
|
+
entry
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
module Job
|
|
50
|
+
def delete
|
|
51
|
+
ActiveJob::Uniqueness.unlock_sidekiq_job!(item)
|
|
52
|
+
super
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
module Queue
|
|
57
|
+
def clear
|
|
58
|
+
each(&:delete)
|
|
59
|
+
super
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
module JobSet
|
|
64
|
+
def clear
|
|
65
|
+
each(&:delete)
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def delete_by_value(name, value)
|
|
70
|
+
ActiveJob::Uniqueness.unlock_sidekiq_job!(Sidekiq.load_json(value)) if super
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
Sidekiq::SortedEntry.prepend ActiveJob::Uniqueness::SidekiqPatch::SortedEntry
|
|
78
|
+
Sidekiq::ScheduledSet.prepend ActiveJob::Uniqueness::SidekiqPatch::ScheduledSet
|
|
79
|
+
Sidekiq::Queue.prepend ActiveJob::Uniqueness::SidekiqPatch::Queue
|
|
80
|
+
Sidekiq::JobSet.prepend ActiveJob::Uniqueness::SidekiqPatch::JobSet
|
|
81
|
+
|
|
82
|
+
sidekiq_version = Gem::Version.new(Sidekiq::VERSION)
|
|
83
|
+
|
|
84
|
+
# Sidekiq 6.2.2 renames Sidekiq::Job to Sidekiq::JobRecord
|
|
85
|
+
# https://github.com/mperham/sidekiq/issues/4955
|
|
86
|
+
if sidekiq_version >= Gem::Version.new('6.2.2')
|
|
87
|
+
Sidekiq::JobRecord.prepend ActiveJob::Uniqueness::SidekiqPatch::Job
|
|
88
|
+
else
|
|
89
|
+
Sidekiq::Job.prepend ActiveJob::Uniqueness::SidekiqPatch::Job
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Global death handlers are introduced in Sidekiq 5.1
|
|
93
|
+
# https://github.com/mperham/sidekiq/blob/e7acb124fbeb0bece0a7c3d657c39a9cc18d72c6/Changes.md#510
|
|
94
|
+
if sidekiq_version >= Gem::Version.new('7.0')
|
|
95
|
+
Sidekiq.default_configuration.death_handlers << ->(job, _ex) { ActiveJob::Uniqueness.unlock_sidekiq_job!(job) }
|
|
96
|
+
elsif sidekiq_version >= Gem::Version.new('5.1')
|
|
97
|
+
Sidekiq.death_handlers << ->(job, _ex) { ActiveJob::Uniqueness.unlock_sidekiq_job!(job) }
|
|
98
|
+
end
|
|
@@ -11,12 +11,13 @@ module ActiveJob
|
|
|
11
11
|
|
|
12
12
|
delegate :lock_manager, :config, to: :'ActiveJob::Uniqueness'
|
|
13
13
|
|
|
14
|
-
attr_reader :lock_key, :lock_ttl, :on_conflict, :job
|
|
14
|
+
attr_reader :lock_key, :lock_ttl, :on_conflict, :on_redis_connection_error, :job
|
|
15
15
|
|
|
16
|
-
def initialize(
|
|
17
|
-
@lock_key = lock_key
|
|
18
|
-
@lock_ttl = (lock_ttl || config.lock_ttl).to_i * 1000 # ms
|
|
19
|
-
@on_conflict = on_conflict || config.on_conflict
|
|
16
|
+
def initialize(job:)
|
|
17
|
+
@lock_key = job.lock_key
|
|
18
|
+
@lock_ttl = (job.lock_options[:lock_ttl] || config.lock_ttl).to_i * 1000 # ms
|
|
19
|
+
@on_conflict = job.lock_options[:on_conflict] || config.on_conflict
|
|
20
|
+
@on_redis_connection_error = job.lock_options[:on_redis_connection_error] || config.on_redis_connection_error
|
|
20
21
|
@job = job
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -60,6 +61,12 @@ module ActiveJob
|
|
|
60
61
|
|
|
61
62
|
handle_conflict(resource: lock_key, on_conflict: on_conflict)
|
|
62
63
|
abort_job
|
|
64
|
+
rescue RedisClient::ConnectionError => e
|
|
65
|
+
handle_redis_connection_error(
|
|
66
|
+
resource: lock_key, on_redis_connection_error:
|
|
67
|
+
on_redis_connection_error, error: e
|
|
68
|
+
)
|
|
69
|
+
abort_job
|
|
63
70
|
end
|
|
64
71
|
|
|
65
72
|
def around_enqueue(block)
|
|
@@ -86,6 +93,14 @@ module ActiveJob
|
|
|
86
93
|
end
|
|
87
94
|
end
|
|
88
95
|
|
|
96
|
+
def handle_redis_connection_error(resource:, on_redis_connection_error:, error:)
|
|
97
|
+
case on_redis_connection_error
|
|
98
|
+
when :raise, nil then raise error
|
|
99
|
+
else
|
|
100
|
+
on_redis_connection_error.call(job, resource: resource, error: error)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
89
104
|
def abort_job
|
|
90
105
|
@job_aborted = true # ActiveJob 4.2 workaround
|
|
91
106
|
|
|
@@ -9,12 +9,16 @@ module ActiveJob
|
|
|
9
9
|
class UntilAndWhileExecuting < Base
|
|
10
10
|
include LockingOnEnqueue
|
|
11
11
|
|
|
12
|
-
attr_reader :runtime_lock_ttl, :on_runtime_conflict
|
|
12
|
+
attr_reader :runtime_lock_key, :runtime_lock_ttl, :on_runtime_conflict
|
|
13
13
|
|
|
14
|
-
def initialize(
|
|
15
|
-
super
|
|
16
|
-
@
|
|
17
|
-
|
|
14
|
+
def initialize(job:)
|
|
15
|
+
super
|
|
16
|
+
@runtime_lock_key = job.runtime_lock_key
|
|
17
|
+
|
|
18
|
+
runtime_lock_ttl_option = job.lock_options[:runtime_lock_ttl]
|
|
19
|
+
@runtime_lock_ttl = runtime_lock_ttl_option.present? ? runtime_lock_ttl_option.to_i * 1000 : lock_ttl
|
|
20
|
+
|
|
21
|
+
@on_runtime_conflict = job.lock_options[:on_runtime_conflict] || on_conflict
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
def before_perform
|
|
@@ -33,10 +37,6 @@ module ActiveJob
|
|
|
33
37
|
ensure
|
|
34
38
|
unlock(resource: runtime_lock_key, event: :runtime_unlock) unless @job_aborted
|
|
35
39
|
end
|
|
36
|
-
|
|
37
|
-
def runtime_lock_key
|
|
38
|
-
[lock_key, 'runtime'].join(':')
|
|
39
|
-
end
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
4
|
-
require 'active_support/core_ext'
|
|
3
|
+
require 'active_job'
|
|
5
4
|
require 'redlock'
|
|
6
|
-
|
|
5
|
+
|
|
7
6
|
require 'active_job/uniqueness/version'
|
|
8
7
|
require 'active_job/uniqueness/errors'
|
|
9
8
|
require 'active_job/uniqueness/log_subscriber'
|
|
10
|
-
require 'active_job/uniqueness/
|
|
9
|
+
require 'active_job/uniqueness/active_job_patch'
|
|
11
10
|
|
|
12
11
|
module ActiveJob
|
|
13
12
|
module Uniqueness
|
|
@@ -32,13 +31,17 @@ module ActiveJob
|
|
|
32
31
|
@lock_manager ||= ActiveJob::Uniqueness::LockManager.new(config.redlock_servers, config.redlock_options)
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
def unlock!(
|
|
36
|
-
lock_manager.delete_locks(ActiveJob::Uniqueness::LockKey.new(
|
|
34
|
+
def unlock!(**args)
|
|
35
|
+
lock_manager.delete_locks(ActiveJob::Uniqueness::LockKey.new(**args).wildcard_key)
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
def test_mode!
|
|
40
39
|
@lock_manager = ActiveJob::Uniqueness::TestLockManager.new
|
|
41
40
|
end
|
|
41
|
+
|
|
42
|
+
def reset_manager!
|
|
43
|
+
@lock_manager = nil
|
|
44
|
+
end
|
|
42
45
|
end
|
|
43
46
|
end
|
|
44
47
|
end
|
data/lib/generators/active_job/uniqueness/templates/config/initializers/active_job_uniqueness.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
ActiveJob::Uniqueness.configure do |config|
|
|
4
4
|
# Global default expiration for lock keys. Each job can define its own ttl via :lock_ttl option.
|
|
5
|
-
#
|
|
5
|
+
# Strategy :until_and_while_executing also accepts :on_runtime_ttl option.
|
|
6
6
|
#
|
|
7
7
|
# config.lock_ttl = 1.day
|
|
8
8
|
|
|
@@ -11,14 +11,21 @@ ActiveJob::Uniqueness.configure do |config|
|
|
|
11
11
|
# config.lock_prefix = 'activejob_uniqueness'
|
|
12
12
|
|
|
13
13
|
# Default action on lock conflict. Can be set per job.
|
|
14
|
-
#
|
|
14
|
+
# Strategy :until_and_while_executing also accepts :on_runtime_conflict option.
|
|
15
15
|
# Allowed values are
|
|
16
16
|
# :raise - raises ActiveJob::Uniqueness::JobNotUnique
|
|
17
17
|
# :log - instruments ActiveSupport::Notifications and logs event to the ActiveJob::Logger
|
|
18
|
-
# proc - custom Proc. For example, ->(job) { job.logger.info(
|
|
18
|
+
# proc - custom Proc. For example, ->(job) { job.logger.info("Job already in queue: #{job.class.name} #{job.arguments.inspect} (#{job.job_id})") }
|
|
19
19
|
#
|
|
20
20
|
# config.on_conflict = :raise
|
|
21
21
|
|
|
22
|
+
# Default action on redis connection error. Can be set per job.
|
|
23
|
+
# Allowed values are
|
|
24
|
+
# :raise - raises ActiveJob::Uniqueness::JobNotUnique
|
|
25
|
+
# proc - custom Proc. For example, ->(job, resource: _, error: _) { job.logger.info("Job already in queue: #{job.class.name} #{job.arguments.inspect} (#{job.job_id})") }
|
|
26
|
+
#
|
|
27
|
+
# config.on_redis_connection_error = :raise
|
|
28
|
+
|
|
22
29
|
# Digest method for lock keys generating. Expected to have `hexdigest` class method.
|
|
23
30
|
#
|
|
24
31
|
# config.digest_method = OpenSSL::Digest::MD5
|
|
@@ -31,7 +38,7 @@ ActiveJob::Uniqueness.configure do |config|
|
|
|
31
38
|
# Custom options for Redlock.
|
|
32
39
|
# Read more at https://github.com/leandromoreira/redlock-rb#redlock-configuration
|
|
33
40
|
#
|
|
34
|
-
# config.redlock_options = {}
|
|
41
|
+
# config.redlock_options = { retry_count: 0 }
|
|
35
42
|
|
|
36
43
|
# Custom strategies.
|
|
37
44
|
# config.lock_strategies = { my_strategy: MyStrategy }
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activejob-uniqueness
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rustam Sharshenov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-12-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activejob
|
|
@@ -17,6 +17,9 @@ dependencies:
|
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '4.2'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '8.1'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -24,68 +27,71 @@ dependencies:
|
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
29
|
version: '4.2'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '8.1'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: redlock
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
30
36
|
requirements:
|
|
31
37
|
- - ">="
|
|
32
38
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
39
|
+
version: '2.0'
|
|
34
40
|
- - "<"
|
|
35
41
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: '
|
|
42
|
+
version: '3'
|
|
37
43
|
type: :runtime
|
|
38
44
|
prerelease: false
|
|
39
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
46
|
requirements:
|
|
41
47
|
- - ">="
|
|
42
48
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: '
|
|
49
|
+
version: '2.0'
|
|
44
50
|
- - "<"
|
|
45
51
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
52
|
+
version: '3'
|
|
47
53
|
- !ruby/object:Gem::Dependency
|
|
48
|
-
name:
|
|
54
|
+
name: appraisal
|
|
49
55
|
requirement: !ruby/object:Gem::Requirement
|
|
50
56
|
requirements:
|
|
51
|
-
- - "
|
|
57
|
+
- - "~>"
|
|
52
58
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
59
|
+
version: 2.3.0
|
|
54
60
|
type: :development
|
|
55
61
|
prerelease: false
|
|
56
62
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
63
|
requirements:
|
|
58
|
-
- - "
|
|
64
|
+
- - "~>"
|
|
59
65
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
66
|
+
version: 2.3.0
|
|
61
67
|
- !ruby/object:Gem::Dependency
|
|
62
|
-
name:
|
|
68
|
+
name: bundler
|
|
63
69
|
requirement: !ruby/object:Gem::Requirement
|
|
64
70
|
requirements:
|
|
65
71
|
- - ">="
|
|
66
72
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '0'
|
|
73
|
+
version: '2.0'
|
|
68
74
|
type: :development
|
|
69
75
|
prerelease: false
|
|
70
76
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
77
|
requirements:
|
|
72
78
|
- - ">="
|
|
73
79
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0'
|
|
80
|
+
version: '2.0'
|
|
75
81
|
- !ruby/object:Gem::Dependency
|
|
76
|
-
name:
|
|
82
|
+
name: pry-byebug
|
|
77
83
|
requirement: !ruby/object:Gem::Requirement
|
|
78
84
|
requirements:
|
|
79
|
-
- - "
|
|
85
|
+
- - ">"
|
|
80
86
|
- !ruby/object:Gem::Version
|
|
81
|
-
version:
|
|
87
|
+
version: 3.6.0
|
|
82
88
|
type: :development
|
|
83
89
|
prerelease: false
|
|
84
90
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
91
|
requirements:
|
|
86
|
-
- - "
|
|
92
|
+
- - ">"
|
|
87
93
|
- !ruby/object:Gem::Version
|
|
88
|
-
version:
|
|
94
|
+
version: 3.6.0
|
|
89
95
|
- !ruby/object:Gem::Dependency
|
|
90
96
|
name: rspec
|
|
91
97
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,6 +106,34 @@ dependencies:
|
|
|
100
106
|
- - "~>"
|
|
101
107
|
- !ruby/object:Gem::Version
|
|
102
108
|
version: '3.0'
|
|
109
|
+
- !ruby/object:Gem::Dependency
|
|
110
|
+
name: rubocop
|
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - "~>"
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '1.28'
|
|
116
|
+
type: :development
|
|
117
|
+
prerelease: false
|
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
119
|
+
requirements:
|
|
120
|
+
- - "~>"
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: '1.28'
|
|
123
|
+
- !ruby/object:Gem::Dependency
|
|
124
|
+
name: rubocop-rspec
|
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - "~>"
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '2.10'
|
|
130
|
+
type: :development
|
|
131
|
+
prerelease: false
|
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - "~>"
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: '2.10'
|
|
103
137
|
description: Ensure uniqueness of your ActiveJob jobs
|
|
104
138
|
email:
|
|
105
139
|
- rustam@sharshenov.com
|
|
@@ -107,24 +141,17 @@ executables: []
|
|
|
107
141
|
extensions: []
|
|
108
142
|
extra_rdoc_files: []
|
|
109
143
|
files:
|
|
110
|
-
- ".gitignore"
|
|
111
|
-
- ".rspec"
|
|
112
|
-
- ".rubocop.yml"
|
|
113
|
-
- ".travis.yml"
|
|
114
144
|
- CHANGELOG.md
|
|
115
|
-
- Gemfile
|
|
116
145
|
- LICENSE.txt
|
|
117
146
|
- README.md
|
|
118
|
-
- Rakefile
|
|
119
|
-
- activejob-uniqueness.gemspec
|
|
120
147
|
- lib/active_job/uniqueness.rb
|
|
148
|
+
- lib/active_job/uniqueness/active_job_patch.rb
|
|
121
149
|
- lib/active_job/uniqueness/configuration.rb
|
|
122
150
|
- lib/active_job/uniqueness/errors.rb
|
|
123
151
|
- lib/active_job/uniqueness/lock_key.rb
|
|
124
152
|
- lib/active_job/uniqueness/lock_manager.rb
|
|
125
153
|
- lib/active_job/uniqueness/log_subscriber.rb
|
|
126
|
-
- lib/active_job/uniqueness/
|
|
127
|
-
- lib/active_job/uniqueness/patch/sidekiq.rb
|
|
154
|
+
- lib/active_job/uniqueness/sidekiq_patch.rb
|
|
128
155
|
- lib/active_job/uniqueness/strategies.rb
|
|
129
156
|
- lib/active_job/uniqueness/strategies/base.rb
|
|
130
157
|
- lib/active_job/uniqueness/strategies/until_and_while_executing.rb
|
|
@@ -143,7 +170,8 @@ licenses:
|
|
|
143
170
|
metadata:
|
|
144
171
|
homepage_uri: https://github.com/veeqo/activejob-uniqueness
|
|
145
172
|
source_code_uri: https://github.com/veeqo/activejob-uniqueness
|
|
146
|
-
changelog_uri: https://github.com/veeqo/activejob-uniqueness/blob/
|
|
173
|
+
changelog_uri: https://github.com/veeqo/activejob-uniqueness/blob/main/CHANGELOG.md
|
|
174
|
+
rubygems_mfa_required: 'true'
|
|
147
175
|
post_install_message:
|
|
148
176
|
rdoc_options: []
|
|
149
177
|
require_paths:
|
|
@@ -152,14 +180,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
152
180
|
requirements:
|
|
153
181
|
- - ">="
|
|
154
182
|
- !ruby/object:Gem::Version
|
|
155
|
-
version: '
|
|
183
|
+
version: '2.5'
|
|
156
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
185
|
requirements:
|
|
158
186
|
- - ">="
|
|
159
187
|
- !ruby/object:Gem::Version
|
|
160
188
|
version: '0'
|
|
161
189
|
requirements: []
|
|
162
|
-
rubygems_version: 3.
|
|
190
|
+
rubygems_version: 3.2.33
|
|
163
191
|
signing_key:
|
|
164
192
|
specification_version: 4
|
|
165
193
|
summary: Ensure uniqueness of your ActiveJob jobs
|
data/.gitignore
DELETED
data/.rspec
DELETED