sidekiq-unique-jobs 4.0.0 → 4.0.7
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.
Potentially problematic release.
This version of sidekiq-unique-jobs might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.simplecov +1 -1
- data/.travis.yml +1 -2
- data/Appraisals +1 -1
- data/CHANGELOG.md +44 -1
- data/Gemfile +1 -2
- data/README.md +49 -51
- data/circle.yml +3 -1
- data/gemfiles/sidekiq_2.17.gemfile +7 -5
- data/gemfiles/sidekiq_3.0.gemfile +6 -4
- data/gemfiles/sidekiq_3.1.gemfile +6 -4
- data/gemfiles/sidekiq_3.2.gemfile +6 -4
- data/gemfiles/sidekiq_3.3.gemfile +6 -4
- data/gemfiles/sidekiq_develop.gemfile +6 -4
- data/lib/sidekiq-unique-jobs.rb +3 -6
- data/lib/sidekiq_unique_jobs/config.rb +1 -6
- data/lib/sidekiq_unique_jobs/constants.rb +17 -0
- data/lib/sidekiq_unique_jobs/core_ext.rb +28 -23
- data/lib/sidekiq_unique_jobs/lock.rb +1 -1
- data/lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb +13 -0
- data/lib/sidekiq_unique_jobs/lock/until_executed.rb +17 -3
- data/lib/sidekiq_unique_jobs/lock/until_executing.rb +4 -0
- data/lib/sidekiq_unique_jobs/lock/until_timeout.rb +9 -2
- data/lib/sidekiq_unique_jobs/lock/while_executing.rb +17 -5
- data/lib/sidekiq_unique_jobs/options_with_fallback.rb +14 -5
- data/lib/sidekiq_unique_jobs/server/middleware.rb +3 -40
- data/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +29 -2
- data/lib/sidekiq_unique_jobs/testing/sidekiq_overrides.rb +6 -2
- data/lib/sidekiq_unique_jobs/timeout_calculator.rb +42 -0
- data/lib/sidekiq_unique_jobs/unique_args.rb +31 -29
- data/lib/sidekiq_unique_jobs/version.rb +1 -1
- data/redis/synchronize.lua +1 -1
- data/sidekiq-unique-jobs.gemspec +1 -2
- data/spec/{workers/unique_worker.rb → jobs/another_unique_job.rb} +3 -3
- data/spec/{workers/queue_worker.rb → jobs/custom_queue_job.rb} +1 -1
- data/spec/jobs/custom_queue_job_with_filter_method.rb +7 -0
- data/spec/{workers/queue_worker_with_filter_proc.rb → jobs/custom_queue_job_with_filter_proc.rb} +2 -3
- data/spec/jobs/expiring_job.rb +4 -0
- data/spec/{workers → jobs}/inline_worker.rb +1 -1
- data/spec/jobs/just_a_worker.rb +8 -0
- data/spec/jobs/main_job.rb +8 -0
- data/spec/{workers/my_worker.rb → jobs/my_job.rb} +2 -3
- data/spec/jobs/my_unique_job.rb +7 -0
- data/spec/{workers → jobs}/plain_class.rb +0 -0
- data/spec/{workers → jobs}/test_class.rb +0 -0
- data/spec/{workers → jobs}/unique_job_with_filter_method.rb +2 -2
- data/spec/{workers/unique_on_all_queues_worker.rb → jobs/unique_on_all_queues_job.rb} +3 -3
- data/spec/jobs/until_and_while_executing_job.rb +8 -0
- data/spec/{workers/another_unique_worker.rb → jobs/until_executed_job.rb} +6 -2
- data/spec/jobs/until_executing_job.rb +8 -0
- data/spec/jobs/until_global_timeout_job.rb +8 -0
- data/spec/{workers/inline_expiration_worker.rb → jobs/until_timeout_job.rb} +2 -2
- data/spec/{workers/after_unlock_worker.rb → jobs/while_executing_job.rb} +2 -3
- data/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb +60 -44
- data/spec/lib/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +39 -0
- data/spec/lib/sidekiq_unique_jobs/lock/until_executed_spec.rb +40 -0
- data/spec/lib/sidekiq_unique_jobs/lock/while_executing_spec.rb +15 -4
- data/spec/lib/sidekiq_unique_jobs/options_with_fallback_spec.rb +25 -0
- data/spec/lib/sidekiq_unique_jobs/scripts_spec.rb +3 -4
- data/spec/lib/sidekiq_unique_jobs/server/middleware_spec.rb +51 -68
- data/spec/lib/sidekiq_unique_jobs/sidekiq_testing_enabled_spec.rb +75 -79
- data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb +2 -2
- data/spec/lib/sidekiq_unique_jobs/{lock/time_calculator_spec.rb → timeout_calculator_spec.rb} +10 -11
- data/spec/lib/sidekiq_unique_jobs/unique_args_spec.rb +28 -45
- data/spec/spec_helper.rb +23 -15
- data/spec/support/unique_macros.rb +20 -1
- metadata +30 -42
- data/lib/sidekiq_unique_jobs/lock/time_calculator.rb +0 -44
- data/spec/workers/after_yield_worker.rb +0 -17
- data/spec/workers/before_yield_worker.rb +0 -9
- data/spec/workers/expiring_worker.rb +0 -4
- data/spec/workers/inline_unlock_order_worker.rb +0 -8
- data/spec/workers/just_a_worker.rb +0 -8
- data/spec/workers/main_job.rb +0 -8
- data/spec/workers/my_unique_worker.rb +0 -8
- data/spec/workers/queue_worker_with_filter_method.rb +0 -7
- data/spec/workers/run_lock_with_retries_worker.rb +0 -12
- data/spec/workers/run_lock_worker.rb +0 -7
- data/spec/workers/while_executing_worker.rb +0 -13
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting do
|
4
|
+
let(:item) do
|
5
|
+
{
|
6
|
+
'jid' => 'maaaahjid',
|
7
|
+
'queue' => 'dupsallowed',
|
8
|
+
'class' => 'UntilAndWhileExecuting',
|
9
|
+
'unique' => 'until_executed',
|
10
|
+
'args' => [1]
|
11
|
+
}
|
12
|
+
end
|
13
|
+
let(:callback) { -> {} }
|
14
|
+
subject { described_class.new(item) }
|
15
|
+
describe '#execute' do
|
16
|
+
before { subject.lock(:client) }
|
17
|
+
let(:runtime_lock) { SidekiqUniqueJobs::Lock::WhileExecuting.new(item, nil) }
|
18
|
+
|
19
|
+
it 'unlocks the unique key before yielding' do
|
20
|
+
expect(SidekiqUniqueJobs::Lock::WhileExecuting)
|
21
|
+
.to receive(:new).with(item, nil)
|
22
|
+
.and_return(runtime_lock)
|
23
|
+
|
24
|
+
expect(callback).to receive(:call)
|
25
|
+
|
26
|
+
subject.execute(callback) do
|
27
|
+
Sidekiq.redis do |c|
|
28
|
+
expect(c.keys('uniquejobs:*').size).to eq(1)
|
29
|
+
end
|
30
|
+
|
31
|
+
10.times { Sidekiq::Client.push(item) }
|
32
|
+
|
33
|
+
Sidekiq.redis do |c|
|
34
|
+
expect(c.keys('uniquejobs:*').size).to eq(2)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted do
|
4
|
+
describe '#execute' do
|
5
|
+
subject { described_class.new(item) }
|
6
|
+
let(:item) do
|
7
|
+
{ 'jid' => 'maaaahjid', 'class' => 'UntilExecutedJob', 'unique' => 'until_executed' }
|
8
|
+
end
|
9
|
+
let(:empty_callback) { -> {} }
|
10
|
+
|
11
|
+
def execute
|
12
|
+
subject.execute(empty_callback)
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when yield fails with Sidekiq::Shutdown' do
|
16
|
+
before do
|
17
|
+
allow(subject).to receive(:after_yield_yield) { fail Sidekiq::Shutdown }
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises Sidekiq::Shutdown' do
|
21
|
+
allow(subject).to receive(:unlock).and_return(true)
|
22
|
+
expect(subject).not_to receive(:unlock)
|
23
|
+
expect(empty_callback).not_to receive(:call)
|
24
|
+
expect { subject.execute(empty_callback) }.to raise_error(Sidekiq::Shutdown)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when yield fails with other errors' do
|
29
|
+
before do
|
30
|
+
allow(subject).to receive(:after_yield_yield) { fail 'Hell' }
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'raises Sidekiq::Shutdown' do
|
34
|
+
expect(subject).to receive(:unlock).and_return(true)
|
35
|
+
expect(empty_callback).to receive(:call)
|
36
|
+
expect { subject.execute(empty_callback) }.to raise_error('Hell')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,9 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do
|
4
|
+
let(:item) do
|
5
|
+
{
|
6
|
+
'jid' => 'maaaahjid',
|
7
|
+
'queue' => 'dupsallowed',
|
8
|
+
'class' => 'UntilAndWhileExecuting',
|
9
|
+
'unique' => 'until_executed',
|
10
|
+
'unique_digest' => 'test_mutex_key',
|
11
|
+
'args' => [1]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
4
15
|
it 'allows only one mutex object to have the lock at a time' do
|
5
16
|
mutexes = (1..10).map do
|
6
|
-
described_class.new(
|
17
|
+
described_class.new(item)
|
7
18
|
end
|
8
19
|
|
9
20
|
x = 0
|
@@ -21,10 +32,10 @@ RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do
|
|
21
32
|
end
|
22
33
|
|
23
34
|
it 'handles auto cleanup correctly' do
|
24
|
-
m = described_class.new(
|
35
|
+
m = described_class.new(item)
|
25
36
|
|
26
37
|
SidekiqUniqueJobs.connection do |conn|
|
27
|
-
conn.set 'test_mutex_key', Time.now.to_i - 1, nx: true
|
38
|
+
conn.set 'test_mutex_key:run', Time.now.to_i - 1, nx: true
|
28
39
|
end
|
29
40
|
|
30
41
|
start = Time.now.to_i
|
@@ -37,7 +48,7 @@ RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do
|
|
37
48
|
end
|
38
49
|
|
39
50
|
it 'maintains mutex semantics' do
|
40
|
-
m = described_class.new(
|
51
|
+
m = described_class.new(item)
|
41
52
|
|
42
53
|
expect do
|
43
54
|
m.synchronize do
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do
|
4
|
+
include described_class
|
5
|
+
subject { self }
|
6
|
+
|
7
|
+
let(:options) { {} }
|
8
|
+
let(:item) { {} }
|
9
|
+
|
10
|
+
describe '#unique_lock' do
|
11
|
+
context 'when options have `unique: true`' do
|
12
|
+
let(:options) { { 'unique' => true } }
|
13
|
+
|
14
|
+
it 'warns when unique is set to true' do
|
15
|
+
expect(subject)
|
16
|
+
.to receive(:warn)
|
17
|
+
.with(
|
18
|
+
'unique: true is no longer valid. Please set it to the type of lock required like: ' \
|
19
|
+
'`unique: :until_executed`')
|
20
|
+
|
21
|
+
subject.unique_lock
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
RSpec.describe SidekiqUniqueJobs::Scripts do
|
3
|
-
include ActiveSupport::Testing::TimeHelpers
|
4
3
|
MD5_DIGEST ||= 'unique'.freeze
|
5
4
|
UNIQUE_KEY ||= 'uniquejobs:unique'.freeze
|
6
5
|
JID ||= 'fuckit'.freeze
|
@@ -36,7 +35,7 @@ RSpec.describe SidekiqUniqueJobs::Scripts do
|
|
36
35
|
context 'when job is unique' do
|
37
36
|
specify { expect(lock_for).to eq(1) }
|
38
37
|
specify do
|
39
|
-
expect(lock_for(0.5
|
38
|
+
expect(lock_for(0.5)).to eq(1)
|
40
39
|
expect(Redis)
|
41
40
|
.to have_key(UNIQUE_KEY)
|
42
41
|
.for_seconds(1)
|
@@ -54,7 +53,7 @@ RSpec.describe SidekiqUniqueJobs::Scripts do
|
|
54
53
|
|
55
54
|
describe '.release_lock' do
|
56
55
|
context 'when job is locked by another jid' do
|
57
|
-
before { expect(lock_for(10
|
56
|
+
before { expect(lock_for(10, 'anotherjid')).to eq(1) }
|
58
57
|
specify { expect(unlock).to eq(0) }
|
59
58
|
after { unlock(UNIQUE_KEY, ANOTHER_JID) }
|
60
59
|
end
|
@@ -65,7 +64,7 @@ RSpec.describe SidekiqUniqueJobs::Scripts do
|
|
65
64
|
|
66
65
|
context 'when job is locked by the same jid' do
|
67
66
|
specify do
|
68
|
-
expect(lock_for(10
|
67
|
+
expect(lock_for(10)).to eq(1)
|
69
68
|
expect(unlock).to eq(1)
|
70
69
|
end
|
71
70
|
end
|
@@ -5,95 +5,78 @@ require 'sidekiq/worker'
|
|
5
5
|
require 'sidekiq_unique_jobs/server/middleware'
|
6
6
|
|
7
7
|
RSpec.describe SidekiqUniqueJobs::Server::Middleware do
|
8
|
-
QUEUE ||= '
|
8
|
+
QUEUE ||= 'working'
|
9
9
|
|
10
10
|
def digest_for(item)
|
11
11
|
SidekiqUniqueJobs::UniqueArgs.digest(item)
|
12
12
|
end
|
13
13
|
|
14
|
+
before do
|
15
|
+
Sidekiq.redis = REDIS
|
16
|
+
Sidekiq.redis(&:flushdb)
|
17
|
+
end
|
18
|
+
|
14
19
|
describe '#call' do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
context 'when unique is disabled' do
|
21
|
+
it 'does not use locking' do
|
22
|
+
allow(subject).to receive(:unique_enabled?).and_return(false)
|
23
|
+
expect(subject).not_to receive(:lock)
|
24
|
+
args = [WhileExecutingJob, { 'class' => 'WhileExecutingJob' }, 'working', nil]
|
25
|
+
subject.call(*args) {}
|
19
26
|
end
|
27
|
+
end
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
29
|
+
context 'when unique is enabled' do
|
30
|
+
it 'executes the lock' do
|
31
|
+
allow(subject).to receive(:unique_enabled?).and_return(true)
|
32
|
+
lock = instance_spy(SidekiqUniqueJobs::Lock::WhileExecuting)
|
33
|
+
expect(lock).to receive(:send).with(:execute, instance_of(Proc)).and_yield
|
34
|
+
expect(subject).to receive(:lock).and_return(lock)
|
28
35
|
|
29
|
-
|
30
|
-
|
31
|
-
expect(c.get(digest_for(item))).to eq('NOT_DELETED')
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
36
|
+
args = [WhileExecutingJob, { 'class' => 'WhileExecutingJob' }, 'working', nil]
|
37
|
+
subject.call(*args) {}
|
35
38
|
end
|
39
|
+
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
Sidekiq.redis do |c|
|
44
|
-
expect(c.ttl(digest_for(item))).to eq(-2) # key does not exist
|
45
|
-
end
|
46
|
-
end
|
41
|
+
describe '#unlock' do
|
42
|
+
it 'does not unlock mutexes it does not own' do
|
43
|
+
jid = UntilExecutedJob.perform_async
|
44
|
+
item = Sidekiq::Queue.new(QUEUE).find_job(jid).item
|
45
|
+
Sidekiq.redis do |c|
|
46
|
+
c.set(digest_for(item), 'NOT_DELETED')
|
47
47
|
end
|
48
|
-
end
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
item = Sidekiq::Queue.new(QUEUE).find_job(jid).item
|
54
|
-
|
55
|
-
subject.call('AfterYieldWorker', item, QUEUE) do
|
56
|
-
Sidekiq.redis do |c|
|
57
|
-
expect(c.get(digest_for(item))).to eq jid
|
58
|
-
end
|
49
|
+
subject.call(UntilExecutedJob.new, item, QUEUE) do
|
50
|
+
Sidekiq.redis do |c|
|
51
|
+
expect(c.get(digest_for(item))).to eq('NOT_DELETED')
|
59
52
|
end
|
60
53
|
end
|
61
54
|
end
|
62
55
|
end
|
63
56
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
subject.call(worker, @item, 'unlock_ordering') { true }
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'unlocks after yield when call errors' do
|
78
|
-
expect(subject).to receive(:unlock)
|
79
|
-
allow(subject).to receive(:after_yield_yield) { fail 'WAT!' }
|
80
|
-
expect { subject.call(worker, @item, 'unlock_ordering') }
|
81
|
-
.to raise_error
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'should not unlock after yield on shutdown, but still raise error' do
|
85
|
-
expect(subject).not_to receive(:unlock)
|
86
|
-
allow(subject).to receive(:after_yield_yield) { fail Sidekiq::Shutdown }
|
87
|
-
expect { subject.call(worker, @item, 'unlock_ordering') }
|
88
|
-
.to raise_error(Sidekiq::Shutdown)
|
57
|
+
describe ':before_yield' do
|
58
|
+
it 'removes the lock before yielding to the worker' do
|
59
|
+
jid = UntilExecutingJob.perform_async
|
60
|
+
item = Sidekiq::Queue.new(QUEUE).find_job(jid).item
|
61
|
+
worker = UntilExecutingJob.new
|
62
|
+
subject.call(worker, item, QUEUE) do
|
63
|
+
Sidekiq.redis do |c|
|
64
|
+
expect(c.ttl(digest_for(item))).to eq(-2) # key does not exist
|
65
|
+
end
|
66
|
+
end
|
89
67
|
end
|
68
|
+
end
|
90
69
|
|
91
|
-
|
92
|
-
|
93
|
-
|
70
|
+
describe ':after_yield' do
|
71
|
+
it 'removes the lock after yielding to the worker' do
|
72
|
+
jid = UntilExecutedJob.perform_async
|
73
|
+
item = Sidekiq::Queue.new(QUEUE).find_job(jid).item
|
94
74
|
|
95
|
-
|
96
|
-
|
75
|
+
subject.call('UntilExecutedJob', item, QUEUE) do
|
76
|
+
Sidekiq.redis do |c|
|
77
|
+
expect(c.get(digest_for(item))).to eq jid
|
78
|
+
end
|
79
|
+
end
|
97
80
|
end
|
98
81
|
end
|
99
82
|
end
|
@@ -2,8 +2,6 @@ require 'spec_helper'
|
|
2
2
|
require 'sidekiq/worker'
|
3
3
|
require 'sidekiq-unique-jobs'
|
4
4
|
require 'sidekiq/scheduled'
|
5
|
-
require 'active_support/core_ext/time'
|
6
|
-
require 'active_support/testing/time_helpers'
|
7
5
|
|
8
6
|
RSpec.describe 'When Sidekiq::Testing is enabled' do
|
9
7
|
describe 'when set to :fake!', sidekiq: :fake do
|
@@ -15,117 +13,117 @@ RSpec.describe 'When Sidekiq::Testing is enabled' do
|
|
15
13
|
context 'with unique worker' do
|
16
14
|
it 'does not push duplicate messages' do
|
17
15
|
param = 'work'
|
18
|
-
expect(
|
19
|
-
expect(
|
20
|
-
expect(
|
21
|
-
expect(
|
22
|
-
expect(
|
23
|
-
expect(
|
16
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
17
|
+
expect(UntilExecutedJob.perform_async(param)).to_not be_nil
|
18
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
19
|
+
expect(UntilExecutedJob).to have_enqueued_job(param)
|
20
|
+
expect(UntilExecutedJob.perform_async(param)).to be_nil
|
21
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
24
22
|
end
|
25
23
|
|
26
24
|
it 'unlocks jobs after draining a worker' do
|
27
25
|
param = 'work'
|
28
26
|
param2 = 'more work'
|
29
|
-
expect(
|
30
|
-
|
31
|
-
|
32
|
-
expect(
|
33
|
-
|
34
|
-
expect(
|
35
|
-
|
36
|
-
|
37
|
-
expect(
|
27
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
28
|
+
UntilExecutedJob.perform_async(param)
|
29
|
+
UntilExecutedJob.perform_async(param2)
|
30
|
+
expect(UntilExecutedJob.jobs.size).to eq(2)
|
31
|
+
UntilExecutedJob.drain
|
32
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
33
|
+
UntilExecutedJob.perform_async(param)
|
34
|
+
UntilExecutedJob.perform_async(param2)
|
35
|
+
expect(UntilExecutedJob.jobs.size).to eq(2)
|
38
36
|
end
|
39
37
|
|
40
38
|
it 'unlocks a single job when calling perform_one' do
|
41
39
|
param = 'work'
|
42
40
|
param2 = 'more work'
|
43
|
-
expect(
|
44
|
-
|
45
|
-
|
46
|
-
expect(
|
47
|
-
|
48
|
-
expect(
|
49
|
-
|
50
|
-
expect(
|
51
|
-
|
52
|
-
expect(
|
41
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
42
|
+
UntilExecutedJob.perform_async(param)
|
43
|
+
UntilExecutedJob.perform_async(param2)
|
44
|
+
expect(UntilExecutedJob.jobs.size).to eq(2)
|
45
|
+
UntilExecutedJob.perform_one
|
46
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
47
|
+
UntilExecutedJob.perform_async(param2)
|
48
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
49
|
+
UntilExecutedJob.perform_async(param)
|
50
|
+
expect(UntilExecutedJob.jobs.size).to eq(2)
|
53
51
|
end
|
54
52
|
|
55
53
|
it 'unlocks jobs cleared from a single worker' do
|
56
54
|
param = 'work'
|
57
55
|
param2 = 'more work'
|
58
|
-
expect(
|
59
|
-
expect(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
expect(
|
64
|
-
expect(
|
65
|
-
|
66
|
-
expect(
|
67
|
-
expect(
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
expect(
|
72
|
-
expect(
|
56
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
57
|
+
expect(AnotherUniqueJob.jobs.size).to eq(0)
|
58
|
+
UntilExecutedJob.perform_async(param)
|
59
|
+
UntilExecutedJob.perform_async(param2)
|
60
|
+
AnotherUniqueJob.perform_async(param)
|
61
|
+
expect(UntilExecutedJob.jobs.size).to eq(2)
|
62
|
+
expect(AnotherUniqueJob.jobs.size).to eq(1)
|
63
|
+
UntilExecutedJob.clear
|
64
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
65
|
+
expect(AnotherUniqueJob.jobs.size).to eq(1)
|
66
|
+
UntilExecutedJob.perform_async(param)
|
67
|
+
UntilExecutedJob.perform_async(param2)
|
68
|
+
AnotherUniqueJob.perform_async(param)
|
69
|
+
expect(UntilExecutedJob.jobs.size).to eq(2)
|
70
|
+
expect(AnotherUniqueJob.jobs.size).to eq(1)
|
73
71
|
end
|
74
72
|
|
75
73
|
it 'handles clearing an empty worker queue' do
|
76
74
|
param = 'work'
|
77
|
-
|
78
|
-
|
79
|
-
expect(
|
80
|
-
expect {
|
75
|
+
UntilExecutedJob.perform_async(param)
|
76
|
+
UntilExecutedJob.clear
|
77
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
78
|
+
expect { UntilExecutedJob.clear }.not_to raise_error
|
81
79
|
end
|
82
80
|
|
83
81
|
it 'unlocks jobs when all workers are cleared' do
|
84
82
|
param = 'work'
|
85
|
-
expect(
|
86
|
-
expect(
|
87
|
-
|
88
|
-
|
89
|
-
expect(
|
90
|
-
expect(
|
83
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
84
|
+
expect(AnotherUniqueJob.jobs.size).to eq(0)
|
85
|
+
UntilExecutedJob.perform_async(param)
|
86
|
+
AnotherUniqueJob.perform_async(param)
|
87
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
88
|
+
expect(AnotherUniqueJob.jobs.size).to eq(1)
|
91
89
|
Sidekiq::Worker.clear_all
|
92
|
-
expect(
|
93
|
-
expect(
|
94
|
-
|
95
|
-
|
96
|
-
expect(
|
97
|
-
expect(
|
90
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
91
|
+
expect(AnotherUniqueJob.jobs.size).to eq(0)
|
92
|
+
UntilExecutedJob.perform_async(param)
|
93
|
+
AnotherUniqueJob.perform_async(param)
|
94
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
95
|
+
expect(AnotherUniqueJob.jobs.size).to eq(1)
|
98
96
|
end
|
99
97
|
|
100
98
|
it 'handles clearing all workers when there are no jobs' do
|
101
99
|
param = 'work'
|
102
|
-
|
103
|
-
|
100
|
+
UntilExecutedJob.perform_async(param)
|
101
|
+
AnotherUniqueJob.perform_async(param)
|
104
102
|
Sidekiq::Worker.clear_all
|
105
|
-
expect(
|
106
|
-
expect(
|
103
|
+
expect(UntilExecutedJob.jobs.size).to eq(0)
|
104
|
+
expect(AnotherUniqueJob.jobs.size).to eq(0)
|
107
105
|
expect { Sidekiq::Worker.jobs.size }.not_to raise_error
|
108
106
|
end
|
109
107
|
|
110
108
|
it 'adds the unique_digest to the message' do
|
111
109
|
param = 'hash'
|
112
|
-
item = { 'class' => '
|
110
|
+
item = { 'class' => 'UntilExecutedJob', 'queue' => 'working', 'args' => [param] }
|
113
111
|
hash = SidekiqUniqueJobs::UniqueArgs.digest(item)
|
114
|
-
expect(
|
115
|
-
expect(
|
116
|
-
expect(
|
112
|
+
expect(UntilExecutedJob.perform_async(param)).to_not be_nil
|
113
|
+
expect(UntilExecutedJob.jobs.size).to eq(1)
|
114
|
+
expect(UntilExecutedJob.jobs.last['unique_digest']).to eq(hash)
|
117
115
|
end
|
118
116
|
end
|
119
117
|
|
120
118
|
context 'with non-unique worker' do
|
121
119
|
it 'pushes duplicates messages' do
|
122
120
|
param = 'work'
|
123
|
-
expect(
|
124
|
-
|
125
|
-
expect(
|
126
|
-
expect(
|
127
|
-
|
128
|
-
expect(
|
121
|
+
expect(MyJob.jobs.size).to eq(0)
|
122
|
+
MyJob.perform_async(param)
|
123
|
+
expect(MyJob.jobs.size).to eq(1)
|
124
|
+
expect(MyJob).to have_enqueued_job(param)
|
125
|
+
MyJob.perform_async(param)
|
126
|
+
expect(MyJob.jobs.size).to eq(2)
|
129
127
|
end
|
130
128
|
end
|
131
129
|
end
|
@@ -140,18 +138,16 @@ RSpec.describe 'When Sidekiq::Testing is enabled' do
|
|
140
138
|
it 'if the unique is kept forever it does not allows to run the job again' do
|
141
139
|
expect(TestClass).to receive(:run).with('args').once
|
142
140
|
|
143
|
-
|
144
|
-
|
141
|
+
UntilGlobalTimeoutJob.perform_async('args')
|
142
|
+
UntilGlobalTimeoutJob.perform_async('args')
|
145
143
|
end
|
146
144
|
|
147
145
|
describe 'when a job is set to run once in 10 minutes' do
|
148
|
-
include ActiveSupport::Testing::TimeHelpers
|
149
|
-
|
150
146
|
context 'when spammed' do
|
151
147
|
it 'only allows 1 call per 10 minutes' do
|
152
148
|
expect(TestClass).to receive(:run).with(1).once
|
153
149
|
100.times do
|
154
|
-
|
150
|
+
UntilTimeoutJob.perform_async(1)
|
155
151
|
end
|
156
152
|
end
|
157
153
|
end
|
@@ -160,12 +156,12 @@ RSpec.describe 'When Sidekiq::Testing is enabled' do
|
|
160
156
|
it 'only allows 1 call per 10 minutes' do
|
161
157
|
expect(TestClass).to receive(:run).with(9).once
|
162
158
|
2.times do
|
163
|
-
|
159
|
+
UntilTimeoutJob.perform_async(9)
|
164
160
|
end
|
165
161
|
|
166
162
|
expect(TestClass).to receive(:run).with(2).once
|
167
163
|
2.times do
|
168
|
-
|
164
|
+
UntilTimeoutJob.perform_async(2)
|
169
165
|
end
|
170
166
|
end
|
171
167
|
end
|