sidekiq-unique-jobs 4.0.8 → 4.0.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sidekiq-unique-jobs might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.fasterer.yml +23 -0
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +12 -1
- data/Gemfile +4 -3
- data/README.md +22 -5
- data/bin/jobs +6 -0
- data/gemfiles/sidekiq_2.15.gemfile +5 -5
- data/gemfiles/sidekiq_2.16.gemfile +5 -5
- data/gemfiles/sidekiq_2.17.gemfile +3 -2
- data/gemfiles/sidekiq_3.0.gemfile +3 -2
- data/gemfiles/sidekiq_3.1.gemfile +3 -2
- data/gemfiles/sidekiq_3.2.gemfile +3 -2
- data/gemfiles/sidekiq_3.3.gemfile +3 -2
- data/gemfiles/sidekiq_develop.gemfile +3 -2
- data/lib/sidekiq-unique-jobs.rb +13 -8
- data/lib/sidekiq/simulator.rb +75 -0
- data/lib/sidekiq_unique_jobs/cli.rb +34 -0
- data/lib/sidekiq_unique_jobs/lock/until_timeout.rb +5 -2
- data/lib/sidekiq_unique_jobs/lock/while_executing.rb +2 -3
- data/lib/sidekiq_unique_jobs/middleware.rb +5 -0
- data/lib/sidekiq_unique_jobs/scripts.rb +3 -7
- data/lib/sidekiq_unique_jobs/util.rb +77 -0
- data/lib/sidekiq_unique_jobs/version.rb +1 -1
- data/rails_example/.gitignore +13 -0
- data/rails_example/Gemfile +20 -0
- data/rails_example/Procfile +2 -0
- data/rails_example/README.rdoc +28 -0
- data/rails_example/Rakefile +6 -0
- data/rails_example/app/assets/images/.keep +0 -0
- data/rails_example/app/assets/javascripts/application.js +16 -0
- data/rails_example/app/assets/stylesheets/application.css +15 -0
- data/rails_example/app/controllers/application_controller.rb +5 -0
- data/rails_example/app/controllers/concerns/.keep +0 -0
- data/rails_example/app/controllers/work_controller.rb +10 -0
- data/rails_example/app/helpers/application_helper.rb +2 -0
- data/rails_example/app/mailers/.keep +0 -0
- data/rails_example/app/models/.keep +0 -0
- data/rails_example/app/models/concerns/.keep +0 -0
- data/rails_example/app/models/post.rb +2 -0
- data/rails_example/app/views/layouts/application.html.erb +15 -0
- data/rails_example/app/workers/simple_worker.rb +11 -0
- data/rails_example/app/workers/spawn_simple_worker.rb +7 -0
- data/rails_example/bin/bundle +3 -0
- data/rails_example/bin/rails +4 -0
- data/rails_example/bin/rake +4 -0
- data/rails_example/bin/setup +29 -0
- data/rails_example/config.ru +4 -0
- data/rails_example/config/application.rb +26 -0
- data/rails_example/config/boot.rb +3 -0
- data/rails_example/config/database.yml +26 -0
- data/rails_example/config/environment.rb +5 -0
- data/rails_example/config/environments/development.rb +41 -0
- data/rails_example/config/environments/production.rb +79 -0
- data/rails_example/config/environments/test.rb +42 -0
- data/rails_example/config/initializers/assets.rb +11 -0
- data/rails_example/config/initializers/backtrace_silencers.rb +8 -0
- data/rails_example/config/initializers/cookies_serializer.rb +3 -0
- data/rails_example/config/initializers/filter_parameter_logging.rb +4 -0
- data/rails_example/config/initializers/inflections.rb +16 -0
- data/rails_example/config/initializers/mime_types.rb +4 -0
- data/rails_example/config/initializers/session_store.rb +3 -0
- data/rails_example/config/initializers/sidekiq.rb +13 -0
- data/rails_example/config/initializers/wrap_parameters.rb +14 -0
- data/rails_example/config/locales/en.yml +23 -0
- data/rails_example/config/routes.rb +5 -0
- data/rails_example/config/secrets.yml +22 -0
- data/rails_example/config/sidekiq.yml +6 -0
- data/rails_example/db/development.sqlite3 +0 -0
- data/rails_example/db/migrate/20151107231835_create_posts.rb +10 -0
- data/rails_example/db/schema.rb +21 -0
- data/rails_example/db/seeds.rb +7 -0
- data/rails_example/db/test.sqlite3 +0 -0
- data/rails_example/lib/assets/.keep +0 -0
- data/rails_example/lib/tasks/.keep +0 -0
- data/rails_example/log/.keep +0 -0
- data/rails_example/public/404.html +67 -0
- data/rails_example/public/422.html +67 -0
- data/rails_example/public/500.html +66 -0
- data/rails_example/public/favicon.ico +0 -0
- data/rails_example/public/robots.txt +5 -0
- data/rails_example/simple.ru +12 -0
- data/rails_example/vendor/assets/javascripts/.keep +0 -0
- data/rails_example/vendor/assets/stylesheets/.keep +0 -0
- data/sidekiq-unique-jobs.gemspec +4 -2
- data/spec/celluloid_with_fallback.rb +9 -8
- data/spec/jobs/simple_worker.rb +11 -0
- data/spec/jobs/spawn_simple_worker.rb +8 -0
- data/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb +53 -1
- data/spec/lib/sidekiq_unique_jobs/lock/until_timeout_spec.rb +26 -0
- data/spec/lib/sidekiq_unique_jobs/options_with_fallback_spec.rb +58 -3
- data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_jobs_spec.rb +6 -1
- data/spec/lib/sidekiq_unique_jobs/unique_args_spec.rb +2 -3
- data/spec/lib/sidekiq_unique_jobs/util_spec.rb +53 -0
- data/spec/spec_helper.rb +1 -0
- metadata +105 -6
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Easiest way to run Sidekiq::Web.
|
2
|
+
# Run with "bundle exec rackup simple.ru"
|
3
|
+
|
4
|
+
require 'sidekiq'
|
5
|
+
|
6
|
+
# A Web process always runs as client, no need to configure server
|
7
|
+
Sidekiq.configure_client do |config|
|
8
|
+
config.redis = { url: 'redis://localhost:6379/0', size: 1, namespace: 'foo' }
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'sidekiq/web'
|
12
|
+
run Sidekiq::Web
|
File without changes
|
File without changes
|
data/sidekiq-unique-jobs.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.homepage = 'https://github.com/mhenrixon/sidekiq-unique-jobs'
|
9
9
|
gem.license = 'WTFPL-2.0'
|
10
10
|
|
11
|
-
|
11
|
+
gem.executables = %w(jobs)
|
12
12
|
gem.files = `git ls-files`.split("\n")
|
13
13
|
gem.test_files = `git ls-files -- test/*`.split("\n")
|
14
14
|
gem.name = 'sidekiq-unique-jobs'
|
@@ -16,9 +16,11 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.post_install_message = 'WARNING: VERSION 4.0.0 HAS BREAKING CHANGES! Please see Readme for info'
|
17
17
|
gem.version = SidekiqUniqueJobs::VERSION
|
18
18
|
gem.add_dependency 'sidekiq', '>= 2.6'
|
19
|
-
gem.
|
19
|
+
gem.add_dependency 'thor', '>= 0'
|
20
|
+
gem.add_development_dependency 'rspec', '~> 3.1'
|
20
21
|
gem.add_development_dependency 'rake'
|
21
22
|
gem.add_development_dependency 'rspec-sidekiq'
|
22
23
|
gem.add_development_dependency 'rubocop'
|
23
24
|
gem.add_development_dependency 'timecop'
|
25
|
+
gem.add_development_dependency 'yard'
|
24
26
|
end
|
@@ -1,17 +1,18 @@
|
|
1
1
|
begin
|
2
2
|
require 'celluloid/current'
|
3
3
|
rescue LoadError
|
4
|
-
warn 'Celluloid is old'
|
4
|
+
warn 'Celluloid is old require the old way'
|
5
|
+
|
5
6
|
begin
|
6
|
-
require 'celluloid'
|
7
|
+
require 'celluloid'
|
7
8
|
rescue LoadError
|
8
|
-
warn '
|
9
|
+
warn 'Sidekiq removed dependency on celluloid'
|
9
10
|
end
|
10
11
|
end
|
12
|
+
|
11
13
|
begin
|
12
|
-
require 'celluloid'
|
13
|
-
|
14
|
-
|
14
|
+
require 'celluloid/test'
|
15
|
+
Celluloid.boot
|
16
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
17
|
+
# do nothing we already know celluloid is not in use
|
15
18
|
end
|
16
|
-
|
17
|
-
Celluloid.boot if defined?(Celluloid)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'sidekiq/worker'
|
3
3
|
require 'sidekiq-unique-jobs'
|
4
|
-
require '
|
4
|
+
require 'rspec/wait'
|
5
5
|
|
6
6
|
RSpec.describe SidekiqUniqueJobs::Client::Middleware do
|
7
7
|
def digest_for(item)
|
@@ -15,6 +15,38 @@ RSpec.describe SidekiqUniqueJobs::Client::Middleware do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
describe 'when a job is already scheduled' do
|
18
|
+
it 'rejects nested subsequent jobs with the same arguments', sidekiq_ver: '>= 3.5.3' do
|
19
|
+
Sidekiq::Testing.disable! do
|
20
|
+
expect(SimpleWorker.perform_async 1).not_to eq(nil)
|
21
|
+
expect(SimpleWorker.perform_async 1).to eq(nil)
|
22
|
+
expect(SpawnSimpleWorker.perform_async 1).not_to eq(nil)
|
23
|
+
|
24
|
+
Sidekiq.redis do |c|
|
25
|
+
expect(c.llen('queue:default')).to eq(1)
|
26
|
+
expect(c.llen('queue:not_default')).to eq(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
Sidekiq::Simulator.process_queue(:not_default) do
|
30
|
+
Sidekiq.redis do |c|
|
31
|
+
expect(c.llen('queue:default')).to eq(1)
|
32
|
+
wait(10).for { c.llen('queue:not_default') }.to eq(0)
|
33
|
+
expect(c.llen('queue:default')).to eq(1)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Sidekiq.redis do |c|
|
38
|
+
expect(c.llen('queue:default')).to eq(1)
|
39
|
+
end
|
40
|
+
|
41
|
+
Sidekiq::Simulator.process_queue(:default) do
|
42
|
+
Sidekiq.redis do |c|
|
43
|
+
expect(c.llen('queue:not_default')).to eq(0)
|
44
|
+
wait(10).for { c.llen('queue:default') }.to eq(0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
18
50
|
it 'rejects new scheduled jobs with the same argument' do
|
19
51
|
MyUniqueJob.perform_in(3600, 1)
|
20
52
|
expect(MyUniqueJob.perform_in(3600, 1)).to eq(nil)
|
@@ -208,4 +240,24 @@ RSpec.describe SidekiqUniqueJobs::Client::Middleware do
|
|
208
240
|
UntilExecutedJob.sidekiq_options log_duplicate_payload: true
|
209
241
|
end
|
210
242
|
end
|
243
|
+
|
244
|
+
describe '#call' do
|
245
|
+
let(:worker_class) { SimpleWorker }
|
246
|
+
let(:item) do
|
247
|
+
{ 'class' => SimpleWorker,
|
248
|
+
'queue' => 'default',
|
249
|
+
'args' => [1] }
|
250
|
+
end
|
251
|
+
let(:queue) { 'default' }
|
252
|
+
context 'when ordinary_or_locked?' do
|
253
|
+
before do
|
254
|
+
allow(subject).to receive(:ordinary_or_locked?).and_return(false)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'returns nil' do
|
258
|
+
expect(subject.call(worker_class, item, queue))
|
259
|
+
.to eq(nil)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
211
263
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SidekiqUniqueJobs::Lock::UntilTimeout do
|
4
|
+
subject { described_class.new(item) }
|
5
|
+
let(:item) do
|
6
|
+
{ 'jid' => 'maaaahjid',
|
7
|
+
'class' => 'UntilExecutedJob',
|
8
|
+
'unique' => 'until_timeout' }
|
9
|
+
end
|
10
|
+
let(:empty_callback) { -> {} }
|
11
|
+
|
12
|
+
describe '#unlock' do
|
13
|
+
context 'when provided :server' do
|
14
|
+
it 'returns true' do
|
15
|
+
expect(subject.unlock(:server)).to eq(true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when provided with anything else than :server' do
|
20
|
+
it 'raises a helpful error message' do
|
21
|
+
expect { subject.unlock(:client) }
|
22
|
+
.to raise_error(ArgumentError, /client middleware can't unlock uniquejobs:*/)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,9 +4,6 @@ RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do
|
|
4
4
|
include described_class
|
5
5
|
subject { self }
|
6
6
|
|
7
|
-
let(:options) { {} }
|
8
|
-
let(:item) { {} }
|
9
|
-
|
10
7
|
describe '#unique_lock' do
|
11
8
|
context 'when options have `unique: true`' do
|
12
9
|
let(:options) { { 'unique' => true } }
|
@@ -21,5 +18,63 @@ RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do
|
|
21
18
|
subject.unique_lock
|
22
19
|
end
|
23
20
|
end
|
21
|
+
|
22
|
+
context 'when options have `unique: :while_executing`' do
|
23
|
+
let(:options) { { 'unique' => 'while_executing' } }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#unique_enabled?' do
|
28
|
+
let(:options) { {} }
|
29
|
+
let(:item) { {} }
|
30
|
+
its(:unique_enabled?) { is_expected.to eq(nil) }
|
31
|
+
|
32
|
+
context 'when options["unique"] is present' do
|
33
|
+
let(:options) { { 'unique' => 'while_executing' } }
|
34
|
+
let(:item) { { 'unique' => 'until_executed' } }
|
35
|
+
its(:unique_enabled?) { is_expected.to eq('while_executing') }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when item["unique"] is present' do
|
39
|
+
let(:options) { {} }
|
40
|
+
let(:item) { { 'unique' => 'until_executed' } }
|
41
|
+
its(:unique_enabled?) { is_expected.to eq('until_executed') }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#unique_disabled?' do
|
46
|
+
let(:options) { {} }
|
47
|
+
let(:item) { {} }
|
48
|
+
its(:unique_disabled?) { is_expected.to be_truthy }
|
49
|
+
|
50
|
+
context 'when options["unique"] is present' do
|
51
|
+
let(:options) { { 'unique' => 'while_executing' } }
|
52
|
+
let(:item) { { 'unique' => 'until_executed' } }
|
53
|
+
its(:unique_disabled?) { is_expected.to be_falsey }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when item["unique"] is present' do
|
57
|
+
let(:options) { {} }
|
58
|
+
let(:item) { { 'unique' => 'until_executed' } }
|
59
|
+
its(:unique_disabled?) { is_expected.to be_falsey }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#options' do
|
64
|
+
context 'when worker_class respond_to get_sidekiq_options' do
|
65
|
+
let(:worker_class) { SimpleWorker }
|
66
|
+
its(:options) { is_expected.to eq(SimpleWorker.get_sidekiq_options) }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when default_worker_options has been configured' do
|
70
|
+
let(:worker_class) { PlainClass }
|
71
|
+
before do
|
72
|
+
allow(Sidekiq)
|
73
|
+
.to receive(:default_worker_options)
|
74
|
+
.and_return('unique' => 'while_executing')
|
75
|
+
end
|
76
|
+
|
77
|
+
its(:options) { is_expected.to eq(Sidekiq.default_worker_options) }
|
78
|
+
end
|
24
79
|
end
|
25
80
|
end
|
@@ -12,9 +12,14 @@ RSpec.describe SidekiqUniqueJobs do
|
|
12
12
|
describe '.configure_server_middleware' do
|
13
13
|
let(:server_config) { class_double(Sidekiq) }
|
14
14
|
let(:server_middleware) { double(Sidekiq::Middleware::Chain) }
|
15
|
+
let(:client_middleware) { double(Sidekiq::Middleware::Chain) }
|
15
16
|
|
16
|
-
it 'adds server middleware when required' do
|
17
|
+
it 'adds client and server middleware when required' do
|
17
18
|
expect(Sidekiq).to receive(:configure_server).and_yield(server_config)
|
19
|
+
|
20
|
+
expect(server_config).to receive(:client_middleware).and_yield(client_middleware)
|
21
|
+
expect(client_middleware).to receive(:add).with(SidekiqUniqueJobs::Client::Middleware)
|
22
|
+
|
18
23
|
expect(server_config).to receive(:server_middleware).and_yield(server_middleware)
|
19
24
|
expect(server_middleware).to receive(:add).with(SidekiqUniqueJobs::Server::Middleware)
|
20
25
|
described_class.configure_server_middleware
|
@@ -5,7 +5,7 @@ RSpec.describe SidekiqUniqueJobs::UniqueArgs do
|
|
5
5
|
subject { described_class.new(item) }
|
6
6
|
|
7
7
|
describe '#unique_digest' do
|
8
|
-
let(:item) { item_options.merge('args' => [1, 2, 'type' => 'it']
|
8
|
+
let(:item) { item_options.merge('args' => [1, 2, 'type' => 'it']) }
|
9
9
|
|
10
10
|
shared_examples 'unique digest' do
|
11
11
|
context 'given another item' do
|
@@ -30,10 +30,9 @@ RSpec.describe SidekiqUniqueJobs::UniqueArgs do
|
|
30
30
|
context 'when unique_args is a proc' do
|
31
31
|
let(:item_options) do
|
32
32
|
{ 'class' => 'UntilExecutedJob', 'queue' => 'myqueue',
|
33
|
-
'unique_args' =>
|
33
|
+
'unique_args' => proc { |args| args[1] } }
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
36
|
it_behaves_like 'unique digest'
|
38
37
|
end
|
39
38
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SidekiqUniqueJobs::Util do
|
4
|
+
let(:keys) { %w(uniquejobs:keyz) }
|
5
|
+
|
6
|
+
def set(key, value)
|
7
|
+
described_class.connection do |c|
|
8
|
+
c.set(key, value)
|
9
|
+
expect(c.keys('*')).to match_array([key])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Sidekiq.redis = REDIS
|
15
|
+
Sidekiq.redis(&:flushdb)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.keys' do
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.del_by' do
|
22
|
+
context 'given a key named "keyz" with value "valz"' do
|
23
|
+
before do
|
24
|
+
set('uniquejobs:keyz', 'valz')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'deletes the keys by pattern' do
|
28
|
+
expect(described_class.del_by('*', count: 100, dry_run: false)).to eq(1)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'deletes the keys by pattern' do
|
32
|
+
expect(described_class.del_by('keyz', count: 100, dry_run: false)).to eq(1)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '.prefix' do
|
38
|
+
context 'when .unique_prefix is nil?' do
|
39
|
+
it 'does not prefix with unique_prefix' do
|
40
|
+
allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return(nil)
|
41
|
+
expect(described_class.prefix('key')).to eq('key')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
before do
|
46
|
+
allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return('test-uniqueness')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns a prefixed key' do
|
50
|
+
expect(described_class.prefix('key')).to eq('test-uniqueness:key')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|