resque-integration 3.4.1
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 +7 -0
- data/.drone.yml +28 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/Appraisals +27 -0
- data/CHANGELOG.md +311 -0
- data/Gemfile +4 -0
- data/README.md +281 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/standalone/progress_bar.js +47 -0
- data/app/controllers/resque/jobs_controller.rb +42 -0
- data/app/controllers/resque/queues/info_controller.rb +9 -0
- data/app/controllers/resque/queues/status_controller.rb +38 -0
- data/app/views/shared/job_progress_bar.html.haml +17 -0
- data/bin/resque-status +59 -0
- data/config/routes.rb +13 -0
- data/config.ru +9 -0
- data/dip.yml +44 -0
- data/docker-compose.development.yml +12 -0
- data/docker-compose.drone.yml +6 -0
- data/docker-compose.yml +10 -0
- data/lib/generators/resque/integration/install/install_generator.rb +38 -0
- data/lib/resque/integration/backtrace.rb +29 -0
- data/lib/resque/integration/configuration.rb +238 -0
- data/lib/resque/integration/continuous.rb +75 -0
- data/lib/resque/integration/engine.rb +103 -0
- data/lib/resque/integration/extensions/job.rb +17 -0
- data/lib/resque/integration/extensions/worker.rb +17 -0
- data/lib/resque/integration/extensions.rb +8 -0
- data/lib/resque/integration/failure_backends/queues_totals.rb +37 -0
- data/lib/resque/integration/failure_backends.rb +7 -0
- data/lib/resque/integration/god.erb +99 -0
- data/lib/resque/integration/hooks.rb +72 -0
- data/lib/resque/integration/logs_rotator.rb +95 -0
- data/lib/resque/integration/monkey_patch/verbose_formatter.rb +10 -0
- data/lib/resque/integration/ordered.rb +142 -0
- data/lib/resque/integration/priority.rb +89 -0
- data/lib/resque/integration/queues_info/age.rb +53 -0
- data/lib/resque/integration/queues_info/config.rb +96 -0
- data/lib/resque/integration/queues_info/size.rb +33 -0
- data/lib/resque/integration/queues_info.rb +55 -0
- data/lib/resque/integration/tasks/hooks.rake +49 -0
- data/lib/resque/integration/tasks/lock.rake +37 -0
- data/lib/resque/integration/tasks/resque.rake +101 -0
- data/lib/resque/integration/unique.rb +218 -0
- data/lib/resque/integration/version.rb +5 -0
- data/lib/resque/integration.rb +146 -0
- data/lib/resque-integration.rb +1 -0
- data/resque-integration.gemspec +40 -0
- data/spec/fixtures/resque_queues.yml +45 -0
- data/spec/resque/controllers/jobs_controller_spec.rb +65 -0
- data/spec/resque/integration/configuration_spec.rb +147 -0
- data/spec/resque/integration/continuous_spec.rb +122 -0
- data/spec/resque/integration/failure_backends/queues_totals_spec.rb +105 -0
- data/spec/resque/integration/ordered_spec.rb +87 -0
- data/spec/resque/integration/priority_spec.rb +94 -0
- data/spec/resque/integration/queues_info_spec.rb +402 -0
- data/spec/resque/integration/unique_spec.rb +184 -0
- data/spec/resque/integration_spec.rb +105 -0
- data/spec/shared/resque_inline.rb +10 -0
- data/spec/spec_helper.rb +28 -0
- data/vendor/assets/images/progressbar/white.gif +0 -0
- data/vendor/assets/javascripts/jquery.progressbar.js +177 -0
- data/vendor/assets/stylesheets/jquery.progressbar.css.erb +33 -0
- data/vendor/assets/stylesheets/jquery.progressbar.no_pipeline.css +33 -0
- metadata +402 -0
@@ -0,0 +1,147 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Resque::Integration::Configuration do
|
6
|
+
let(:config) do
|
7
|
+
File.stub(:exists? => true)
|
8
|
+
File.stub(:read)
|
9
|
+
ERB.stub_chain(:new, :result)
|
10
|
+
YAML.stub(:load => config_yaml)
|
11
|
+
described_class.new('path/to/config.yml')
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:config_yaml) { {} }
|
15
|
+
|
16
|
+
describe '#schedule_file' do
|
17
|
+
let(:config_yaml) { {'resque' => {'schedule_file' => 'schedule.yml'}} }
|
18
|
+
|
19
|
+
it { expect(config.schedule_file).to eq 'schedule.yml' }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#log_level' do
|
23
|
+
context 'when default' do
|
24
|
+
it { expect(config.log_level).to eq 1 }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when defined' do
|
28
|
+
let(:config_yaml) { {'resque' => {'log_level' => 2}} }
|
29
|
+
|
30
|
+
it { expect(config.log_level).to eq 2 }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#resque_scheduler?' do
|
35
|
+
context 'when default' do
|
36
|
+
it { expect(config.resque_scheduler?).to be_truthy }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when defined' do
|
40
|
+
let(:config_yaml) { {'resque' => {'scheduler' => 'no'}} }
|
41
|
+
|
42
|
+
it { expect(config.resque_scheduler?).to be_falsey }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#run_at_exit_hooks?' do
|
47
|
+
context 'when default' do
|
48
|
+
it { expect(config.resque_scheduler?).to be_truthy }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when defined' do
|
52
|
+
let(:config_yaml) { {'resque' => {'run_at_exit_hooks' => 'no'}} }
|
53
|
+
|
54
|
+
it { expect(config.run_at_exit_hooks?).to be_falsey }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Resque::Integration::Configuration::Notifier do
|
60
|
+
context 'when NilClass given as config' do
|
61
|
+
subject(:config) { described_class::new(nil) }
|
62
|
+
|
63
|
+
it { should_not be_enabled }
|
64
|
+
its(:include_payload?) { should be_truthy }
|
65
|
+
its(:to) { should be_empty }
|
66
|
+
its(:from) { should eq 'no_reply@gmail.com' }
|
67
|
+
its(:mail) { should eq :alert }
|
68
|
+
its(:mailer) { should eq 'ResqueFailedJobMailer::Mailer' }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when Hash given as config' do
|
72
|
+
let :configuration do
|
73
|
+
{to: ['to1@mail', 'to2@mail'],
|
74
|
+
from: 'from@mail',
|
75
|
+
enabled: false,
|
76
|
+
include_payload: false,
|
77
|
+
mail: 'notify',
|
78
|
+
mailer: 'MyMailer'}
|
79
|
+
end
|
80
|
+
|
81
|
+
subject(:config) { described_class::new(configuration) }
|
82
|
+
|
83
|
+
it { should_not be_enabled }
|
84
|
+
its(:include_payload?) { should be_falsey }
|
85
|
+
its(:to) { should include 'to1@mail' }
|
86
|
+
its(:to) { should include 'to2@mail' }
|
87
|
+
its(:from) { should eq 'from@mail' }
|
88
|
+
its(:mail) { should eq :notify }
|
89
|
+
its(:mailer) { should eq 'MyMailer' }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe Resque::Integration::Configuration::Worker do
|
94
|
+
describe '.new' do
|
95
|
+
context 'when Integer given as config' do
|
96
|
+
subject(:config) { described_class::new(:default, 2) }
|
97
|
+
|
98
|
+
its(:queue) { should eq :default }
|
99
|
+
its(:count) { should eq 2 }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when Hash given as config' do
|
103
|
+
subject(:config) { described_class::new(:default, :count => 2) }
|
104
|
+
|
105
|
+
its(:queue) { should eq :default }
|
106
|
+
its(:count) { should eq 2 }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#count' do
|
111
|
+
context 'when initialized without count paramter' do
|
112
|
+
subject { described_class::new(:default, {}) }
|
113
|
+
|
114
|
+
its(:count) { should eq 1 }
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when initialized with count <= 0' do
|
118
|
+
subject { described_class::new(:default, :count => 0) }
|
119
|
+
|
120
|
+
its(:count) { should eq 1 }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#env' do
|
125
|
+
let :config do
|
126
|
+
described_class.new(:default,
|
127
|
+
:count => 2,
|
128
|
+
:jobs_per_fork => 10,
|
129
|
+
:minutes_per_fork => 5,
|
130
|
+
:shuffle => true,
|
131
|
+
:env => {:VAR => 2})
|
132
|
+
end
|
133
|
+
|
134
|
+
subject { config.env }
|
135
|
+
|
136
|
+
its([:QUEUE]) { should eq 'default' }
|
137
|
+
its([:JOBS_PER_FORK]) { should eq '10' }
|
138
|
+
its([:MINUTES_PER_FORK]) { should eq '5' }
|
139
|
+
its([:SHUFFLE]) { should eq '1' }
|
140
|
+
its([:VAR]) { should eq '2' }
|
141
|
+
|
142
|
+
context "when shuffle is disabled" do
|
143
|
+
let(:config) { described_class.new(:default, shuffle: false) }
|
144
|
+
its([:SHUFFLE]) { should be_nil }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Resque::Integration::Continuous do
|
6
|
+
context 'when applied to non-unique job' do
|
7
|
+
class ContinuousJobTest
|
8
|
+
include Resque::Integration
|
9
|
+
|
10
|
+
queue :continuous_test
|
11
|
+
continuous
|
12
|
+
|
13
|
+
def self.perform(id)
|
14
|
+
continue(id + 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should re-enqueue the job' do
|
19
|
+
Resque.enqueue(ContinuousJobTest, 1)
|
20
|
+
|
21
|
+
job = Resque.reserve(ContinuousJobTest.queue)
|
22
|
+
job.should be_a(Resque::Job)
|
23
|
+
job.payload['args'].should eq [1]
|
24
|
+
job.perform
|
25
|
+
|
26
|
+
job2 = Resque.reserve(ContinuousJobTest.queue)
|
27
|
+
job2.should be_a(Resque::Job)
|
28
|
+
job2.payload['args'].should eq [2]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when applied to unique job' do
|
33
|
+
class ContinuousUniqueJobTest
|
34
|
+
include Resque::Integration
|
35
|
+
|
36
|
+
queue :unique_continuous_test
|
37
|
+
continuous
|
38
|
+
unique { |x, y| x }
|
39
|
+
|
40
|
+
def self.execute(x, y)
|
41
|
+
continue(x, y + 1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should re-enqueue the job regardless of any locks' do
|
46
|
+
ContinuousUniqueJobTest.enqueue(1, 1)
|
47
|
+
|
48
|
+
job = Resque.reserve(ContinuousUniqueJobTest.queue)
|
49
|
+
job.should be_a(Resque::Job)
|
50
|
+
|
51
|
+
# meta prepend meta_id arg, so we just ignore it here
|
52
|
+
job.payload['args'][1..-1].should eq [1, 1]
|
53
|
+
job.perform
|
54
|
+
|
55
|
+
ContinuousUniqueJobTest.should be_locked(1, 2)
|
56
|
+
ContinuousUniqueJobTest.should be_enqueued(1, 2)
|
57
|
+
|
58
|
+
job2 = Resque.reserve(ContinuousUniqueJobTest.queue)
|
59
|
+
job2.should be_a(Resque::Job)
|
60
|
+
job2.payload['args'][1..-1].should eq [1, 2]
|
61
|
+
|
62
|
+
# clean the queue
|
63
|
+
ContinuousUniqueJobTest.dequeue(1)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should not finish meta' do
|
67
|
+
meta = ContinuousUniqueJobTest.enqueue(2, 1)
|
68
|
+
|
69
|
+
job = Resque.reserve(ContinuousUniqueJobTest.queue)
|
70
|
+
job.perform
|
71
|
+
meta.reload!
|
72
|
+
|
73
|
+
meta2 = ContinuousUniqueJobTest.enqueued?(2, 2)
|
74
|
+
|
75
|
+
meta2.started_at.should eq meta.started_at
|
76
|
+
meta2.enqueued_at.should eq meta.enqueued_at
|
77
|
+
meta2.data.should eq meta.data
|
78
|
+
meta2.should be_working
|
79
|
+
|
80
|
+
# clean the queue
|
81
|
+
ContinuousUniqueJobTest.dequeue(2)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should enqueue job with the same meta_id' do
|
85
|
+
ContinuousUniqueJobTest.enqueue(3, 1)
|
86
|
+
|
87
|
+
job1 = Resque.reserve(ContinuousUniqueJobTest.queue)
|
88
|
+
meta1 = job1.payload['args'].first
|
89
|
+
|
90
|
+
job1.perform
|
91
|
+
|
92
|
+
job2 = Resque.reserve(ContinuousUniqueJobTest.queue)
|
93
|
+
meta2 = job2.payload['args'].first
|
94
|
+
|
95
|
+
meta1.should eq meta2
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when called without arguments' do
|
100
|
+
class ContinuousWithoutArgsJobTest
|
101
|
+
include Resque::Integration
|
102
|
+
|
103
|
+
queue :continuous_without_args_test
|
104
|
+
continuous
|
105
|
+
unique
|
106
|
+
|
107
|
+
def self.execute(x)
|
108
|
+
continue
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should re-enqueue job with same arguments' do
|
113
|
+
ContinuousWithoutArgsJobTest.enqueue(1)
|
114
|
+
|
115
|
+
job = Resque.reserve(ContinuousWithoutArgsJobTest.queue)
|
116
|
+
job.should be_a(Resque::Job)
|
117
|
+
job.perform
|
118
|
+
|
119
|
+
ContinuousWithoutArgsJobTest.should be_enqueued(1)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Resque::Integration::FailureBackends::QueuesTotals do
|
4
|
+
let(:failure) { double('UnbelievableError') }
|
5
|
+
let(:worker) { double('Worker') }
|
6
|
+
let(:payload) { double('Payload') }
|
7
|
+
|
8
|
+
describe '#save' do
|
9
|
+
let(:queue) { 'images' }
|
10
|
+
let(:backend) { described_class.new(failure, worker, queue, payload) }
|
11
|
+
|
12
|
+
before { stub_const('Resque::Integration::FailureBackends::QueuesTotals::MAX_COUNTER_VALUE', 3) }
|
13
|
+
|
14
|
+
it 'increments failures count for specified queue' do
|
15
|
+
expect do
|
16
|
+
2.times { backend.save }
|
17
|
+
end.to change { described_class.count(queue) }.from(0).to(2)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when counter overflows' do
|
21
|
+
it 'resets failures count for specified queue to 1' do
|
22
|
+
expect do
|
23
|
+
3.times { backend.save }
|
24
|
+
end.to change { described_class.count(queue) }.from(0).to(1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.count' do
|
30
|
+
let(:images_queue) { 'images' }
|
31
|
+
let(:products_queue) { 'products' }
|
32
|
+
let(:images_failure_backend) { described_class.new(failure, worker, images_queue, payload) }
|
33
|
+
let(:products_failure_backend) { described_class.new(failure, worker, products_queue, payload) }
|
34
|
+
|
35
|
+
before do
|
36
|
+
2.times { images_failure_backend.save }
|
37
|
+
3.times { products_failure_backend.save }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with specified queue' do
|
41
|
+
it 'returns failures count for specified queue' do
|
42
|
+
expect(described_class.count(images_queue)).to eq(2)
|
43
|
+
expect(described_class.count(products_queue)).to eq(3)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with queue which has no failures' do
|
48
|
+
it 'returns 0' do
|
49
|
+
expect(described_class.count('not_failed')).to eq(0)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'without specified queue' do
|
54
|
+
it 'returns aggregated failures count from all queues' do
|
55
|
+
expect(described_class.count).to eq(5)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '.queues' do
|
61
|
+
context 'when has failures data' do
|
62
|
+
let(:images_queue) { 'images' }
|
63
|
+
let(:products_queue) { 'products' }
|
64
|
+
|
65
|
+
before do
|
66
|
+
described_class.new(failure, worker, images_queue, payload).save
|
67
|
+
described_class.new(failure, worker, products_queue, payload).save
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns names of failed queues' do
|
71
|
+
expect(described_class.queues).to match_array([images_queue, products_queue])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when does not have failures data' do
|
76
|
+
it { expect(described_class.queues).to be_empty }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '.clear' do
|
81
|
+
let(:images_queue) { 'images' }
|
82
|
+
let(:products_queue) { 'products' }
|
83
|
+
|
84
|
+
before do
|
85
|
+
described_class.new(failure, worker, images_queue, payload).save
|
86
|
+
described_class.new(failure, worker, products_queue, payload).save
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with specified queue' do
|
90
|
+
it 'deletes counter data for specified queue' do
|
91
|
+
expect { described_class.clear(products_queue) }.to change { described_class.count }.from(2).to(1)
|
92
|
+
expect(described_class.count(images_queue)).to eq(1)
|
93
|
+
expect(described_class.count(products_queue)).to eq(0)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'without specified queue' do
|
98
|
+
it 'deletes counter data for all queues' do
|
99
|
+
expect { described_class.clear }.to change { described_class.count }.from(2).to(0)
|
100
|
+
expect(described_class.count(images_queue)).to eq(0)
|
101
|
+
expect(described_class.count(products_queue)).to eq(0)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Resque::Integration::Ordered do
|
4
|
+
class TestJob
|
5
|
+
include Resque::Integration
|
6
|
+
|
7
|
+
unique { |company_id, param1| [company_id] }
|
8
|
+
ordered max_iterations: 2
|
9
|
+
end
|
10
|
+
|
11
|
+
class UniqueTestJob
|
12
|
+
include Resque::Integration
|
13
|
+
|
14
|
+
unique { |company_id, param1| [company_id] }
|
15
|
+
ordered max_iterations: 2, unique: ->(_company_id, param1) { [param1] }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "push args to separate queue" do
|
19
|
+
ordered_meta1 = TestJob.enqueue(1, 10)
|
20
|
+
ordered_meta2 = TestJob.enqueue(1, 20)
|
21
|
+
|
22
|
+
meta_id = TestJob.meta_id(1, 10)
|
23
|
+
args_key = TestJob.ordered_queue_key(meta_id)
|
24
|
+
|
25
|
+
expect(TestJob).to be_enqueued(1)
|
26
|
+
expect(TestJob.ordered_queue_size(meta_id)).to eq 2
|
27
|
+
|
28
|
+
job_args = Resque.decode(Resque.redis.lpop(args_key))
|
29
|
+
expect(job_args[0]).to eq ordered_meta1.meta_id
|
30
|
+
|
31
|
+
job_args = Resque.decode(Resque.redis.lpop(args_key))
|
32
|
+
expect(job_args[0]).to eq ordered_meta2.meta_id
|
33
|
+
end
|
34
|
+
|
35
|
+
it "execute jobs by each args" do
|
36
|
+
TestJob.enqueue(1, 10)
|
37
|
+
TestJob.enqueue(1, 20)
|
38
|
+
|
39
|
+
expect(TestJob).to receive(:execute).with(kind_of(Resque::Plugins::Meta::Metadata), 1, 10).ordered
|
40
|
+
expect(TestJob).to receive(:execute).with(kind_of(Resque::Plugins::Meta::Metadata), 1, 20).ordered
|
41
|
+
expect(TestJob).to_not receive(:continue)
|
42
|
+
|
43
|
+
meta_id = TestJob.meta_id(1, 10)
|
44
|
+
TestJob.perform(meta_id)
|
45
|
+
expect(TestJob.ordered_queue_size(meta_id)).to eq 0
|
46
|
+
end
|
47
|
+
|
48
|
+
it "reenqueue job after max iterations reached" do
|
49
|
+
TestJob.enqueue(1, 10)
|
50
|
+
TestJob.enqueue(1, 20)
|
51
|
+
TestJob.enqueue(1, 30)
|
52
|
+
TestJob.enqueue(1, 40)
|
53
|
+
|
54
|
+
expect(TestJob).to receive(:execute).with(kind_of(Resque::Plugins::Meta::Metadata), 1, 10).ordered
|
55
|
+
expect(TestJob).to receive(:execute).with(kind_of(Resque::Plugins::Meta::Metadata), 1, 20).ordered
|
56
|
+
expect(TestJob).to_not receive(:execute).with(kind_of(Resque::Plugins::Meta::Metadata), 1, 30).ordered
|
57
|
+
expect(TestJob).to_not receive(:execute).with(kind_of(Resque::Plugins::Meta::Metadata), 1, 40).ordered
|
58
|
+
expect(TestJob).to receive(:continue)
|
59
|
+
|
60
|
+
meta_id = TestJob.meta_id(1, 10)
|
61
|
+
TestJob.perform(meta_id)
|
62
|
+
expect(TestJob.ordered_queue_size(meta_id)).to eq 2
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'uniqueness' do
|
66
|
+
it 'perform with unique args only once' do
|
67
|
+
UniqueTestJob.enqueue(1, 10)
|
68
|
+
UniqueTestJob.enqueue(1, 20)
|
69
|
+
UniqueTestJob.enqueue(1, 10)
|
70
|
+
|
71
|
+
expect(UniqueTestJob).to receive(:execute).once.with(kind_of(Resque::Plugins::Meta::Metadata), 1, 10).ordered
|
72
|
+
expect(UniqueTestJob).to receive(:execute).once.with(kind_of(Resque::Plugins::Meta::Metadata), 1, 20).ordered
|
73
|
+
expect(UniqueTestJob).to_not receive(:continue)
|
74
|
+
|
75
|
+
meta_id = UniqueTestJob.meta_id(1, 10)
|
76
|
+
UniqueTestJob.perform(meta_id)
|
77
|
+
expect(UniqueTestJob.ordered_queue_size(meta_id)).to eq 0
|
78
|
+
expect(UniqueTestJob.uniqueness.size(meta_id)).to eq 0
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'enqueue unique jobs with equal meta' do
|
82
|
+
meta = UniqueTestJob.enqueue(1, 10)
|
83
|
+
expect(meta.meta_id).to eq UniqueTestJob.enqueue(1, 10).meta_id
|
84
|
+
expect(meta.meta_id).to_not eq UniqueTestJob.enqueue(1, 20).meta_id
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Resque::Integration::Priority do
|
4
|
+
class JobWithPriority
|
5
|
+
include Resque::Integration
|
6
|
+
|
7
|
+
queue :foo
|
8
|
+
prioritized
|
9
|
+
|
10
|
+
def self.perform(id, params)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class UniqueJobWithPriority
|
15
|
+
include Resque::Integration
|
16
|
+
|
17
|
+
queue :foo
|
18
|
+
unique do |id, params|
|
19
|
+
[id, params["param"]]
|
20
|
+
end
|
21
|
+
prioritized
|
22
|
+
|
23
|
+
def self.execute(id, params)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#enqueue' do
|
28
|
+
it 'enqueue to priority queue' do
|
29
|
+
JobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
30
|
+
|
31
|
+
expect(Resque.size(:foo)).to eq(0)
|
32
|
+
expect(Resque.size(:foo_low)).to eq(0)
|
33
|
+
expect(Resque.size(:foo_high)).to eq(1)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'enqueue to default queue' do
|
37
|
+
JobWithPriority.enqueue(1, param: 'one')
|
38
|
+
|
39
|
+
expect(Resque.size(:foo)).to eq(1)
|
40
|
+
expect(Resque.size(:foo_low)).to eq(0)
|
41
|
+
expect(Resque.size(:foo_high)).to eq(0)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'enqueue only one job' do
|
45
|
+
meta1 = UniqueJobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
46
|
+
meta2 = UniqueJobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
47
|
+
|
48
|
+
expect(meta1.meta_id).to eq(meta2.meta_id)
|
49
|
+
|
50
|
+
expect(Resque.size(:foo)).to eq(0)
|
51
|
+
expect(Resque.size(:foo_low)).to eq(0)
|
52
|
+
expect(Resque.size(:foo_high)).to eq(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#dequeue' do
|
57
|
+
it 'dequeue simple job with high priority' do
|
58
|
+
JobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
59
|
+
JobWithPriority.enqueue_with_priority(:high, 2, param: 'two')
|
60
|
+
expect(Resque.size(:foo_high)).to eq(2)
|
61
|
+
|
62
|
+
JobWithPriority.dequeue(:high, 1, param: 'one')
|
63
|
+
expect(Resque.size(:foo_high)).to eq(1)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'dequeue unique job with high priority' do
|
67
|
+
UniqueJobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
68
|
+
UniqueJobWithPriority.enqueue_with_priority(:high, 2, param: 'two')
|
69
|
+
expect(Resque.size(:foo_high)).to eq(2)
|
70
|
+
|
71
|
+
UniqueJobWithPriority.dequeue(:high, 1, param: 'one')
|
72
|
+
expect(Resque.size(:foo_high)).to eq(1)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#perform' do
|
77
|
+
include_context 'resque inline'
|
78
|
+
|
79
|
+
it 'executes job' do
|
80
|
+
expect(JobWithPriority).to receive(:perform).with(1, 'param' => 'one')
|
81
|
+
expect(JobWithPriority).to receive(:perform).with(2, 'param' => 'two')
|
82
|
+
|
83
|
+
JobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
84
|
+
JobWithPriority.enqueue_with_priority(:high, 2, param: 'two')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'executes job' do
|
88
|
+
expect(UniqueJobWithPriority).to receive(:execute).twice.and_call_original
|
89
|
+
|
90
|
+
UniqueJobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
91
|
+
UniqueJobWithPriority.enqueue_with_priority(:high, 1, param: 'one')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|