delayed_job_groups_plugin 0.1.2 → 0.4.2
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 +5 -5
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +17 -16
- data/Appraisals +30 -0
- data/CHANGELOG.md +22 -2
- data/Gemfile +2 -0
- data/README.md +2 -2
- data/Rakefile +2 -0
- data/delayed_job_groups.gemspec +18 -17
- data/gemfiles/rails_4.2.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +9 -0
- data/gemfiles/rails_5.2.gemfile +9 -0
- data/gemfiles/rails_6.0.gemfile +8 -0
- data/lib/delayed/job_groups/compatibility.rb +2 -2
- data/lib/delayed/job_groups/job_extensions.rb +7 -8
- data/lib/delayed/job_groups/job_group.rb +9 -17
- data/lib/delayed/job_groups/plugin.rb +4 -20
- data/lib/delayed/job_groups/version.rb +2 -2
- data/lib/delayed/job_groups/yaml_loader.rb +17 -0
- data/lib/delayed_job_groups_plugin.rb +2 -1
- data/lib/generators/delayed_job_groups_plugin/install_generator.rb +2 -2
- data/lib/generators/delayed_job_groups_plugin/templates/migration.rb +1 -1
- data/spec/db/schema.rb +2 -2
- data/spec/delayed/job_groups/job_group_spec.rb +22 -23
- data/spec/delayed/job_groups/plugin_spec.rb +79 -84
- data/spec/delayed/job_groups/yaml_loader_spec.rb +43 -0
- data/spec/spec_helper.rb +12 -12
- data/spec/support/destroyed_model.rb +3 -3
- metadata +90 -31
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support'
|
4
4
|
require 'active_record'
|
@@ -8,6 +8,7 @@ require 'delayed/job_groups/compatibility'
|
|
8
8
|
require 'delayed/job_groups/job_extensions'
|
9
9
|
require 'delayed/job_groups/job_group'
|
10
10
|
require 'delayed/job_groups/plugin'
|
11
|
+
require 'delayed/job_groups/yaml_loader'
|
11
12
|
require 'delayed/job_groups/version'
|
12
13
|
|
13
14
|
Delayed::Backend::ActiveRecord::Job.send(:include, Delayed::JobGroups::JobExtensions)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails/generators'
|
4
4
|
require 'rails/generators/migration'
|
@@ -8,7 +8,7 @@ module DelayedJobGroupsPlugin
|
|
8
8
|
class InstallGenerator < Rails::Generators::Base
|
9
9
|
include Rails::Generators::Migration
|
10
10
|
|
11
|
-
|
11
|
+
source_paths << File.join(File.dirname(__FILE__), 'templates')
|
12
12
|
|
13
13
|
def create_migration_file
|
14
14
|
migration_template('migration.rb', 'db/migrate/create_delayed_job_groups.rb')
|
data/spec/db/schema.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
3
|
describe Delayed::JobGroups::JobGroup do
|
6
4
|
|
@@ -19,7 +17,7 @@ describe Delayed::JobGroups::JobGroup do
|
|
19
17
|
|
20
18
|
before do
|
21
19
|
Timecop.freeze(current_time)
|
22
|
-
Delayed::Job.
|
20
|
+
allow(Delayed::Job).to receive(:enqueue)
|
23
21
|
end
|
24
22
|
|
25
23
|
after do
|
@@ -28,21 +26,21 @@ describe Delayed::JobGroups::JobGroup do
|
|
28
26
|
|
29
27
|
shared_examples "the job group was completed" do
|
30
28
|
it "queues the completion job" do
|
31
|
-
Delayed::Job.
|
29
|
+
expect(Delayed::Job).to have_received(:enqueue).with(on_completion_job, on_completion_job_options)
|
32
30
|
end
|
33
31
|
|
34
32
|
it "destroys the job group" do
|
35
|
-
job_group.
|
33
|
+
expect(job_group).to have_been_destroyed
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
37
|
shared_examples "the job group was not completed" do
|
40
38
|
it "does not queue the completion job" do
|
41
|
-
Delayed::Job.
|
39
|
+
expect(Delayed::Job).not_to have_received(:enqueue)
|
42
40
|
end
|
43
41
|
|
44
42
|
it "does not destroy the job group" do
|
45
|
-
job_group.
|
43
|
+
expect(job_group).not_to have_been_destroyed
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
@@ -51,15 +49,16 @@ describe Delayed::JobGroups::JobGroup do
|
|
51
49
|
context "when no jobs exist" do
|
52
50
|
before { job_group.mark_queueing_complete }
|
53
51
|
|
54
|
-
it {
|
52
|
+
it { is_expected.to be_queueing_complete }
|
55
53
|
it_behaves_like "the job group was completed"
|
56
54
|
end
|
57
55
|
|
58
56
|
context "when no jobs exist but the job group is blocked" do
|
59
57
|
let(:blocked) { true }
|
58
|
+
|
60
59
|
before { job_group.mark_queueing_complete }
|
61
60
|
|
62
|
-
it {
|
61
|
+
it { is_expected.to be_queueing_complete }
|
63
62
|
it_behaves_like "the job group was not completed"
|
64
63
|
end
|
65
64
|
|
@@ -69,7 +68,7 @@ describe Delayed::JobGroups::JobGroup do
|
|
69
68
|
job_group.mark_queueing_complete
|
70
69
|
end
|
71
70
|
|
72
|
-
it {
|
71
|
+
it { is_expected.to be_queueing_complete }
|
73
72
|
it_behaves_like "the job group was not completed"
|
74
73
|
end
|
75
74
|
end
|
@@ -117,11 +116,11 @@ describe Delayed::JobGroups::JobGroup do
|
|
117
116
|
include_context "complete job and check job group complete"
|
118
117
|
|
119
118
|
it "queues the completion job with empty options" do
|
120
|
-
Delayed::Job.
|
119
|
+
expect(Delayed::Job).to have_received(:enqueue).with(on_completion_job, {})
|
121
120
|
end
|
122
121
|
|
123
122
|
it "destroys the job group" do
|
124
|
-
job_group.
|
123
|
+
expect(job_group).to have_been_destroyed
|
125
124
|
end
|
126
125
|
end
|
127
126
|
|
@@ -131,11 +130,11 @@ describe Delayed::JobGroups::JobGroup do
|
|
131
130
|
include_context "complete job and check job group complete"
|
132
131
|
|
133
132
|
it "doesn't queues the non-existent completion job" do
|
134
|
-
Delayed::Job.
|
133
|
+
expect(Delayed::Job).not_to have_received(:enqueue)
|
135
134
|
end
|
136
135
|
|
137
136
|
it "destroys the job group" do
|
138
|
-
job_group.
|
137
|
+
expect(job_group).to have_been_destroyed
|
139
138
|
end
|
140
139
|
end
|
141
140
|
end
|
@@ -149,7 +148,7 @@ describe Delayed::JobGroups::JobGroup do
|
|
149
148
|
|
150
149
|
shared_examples "it enqueues the job in the correct blocked state" do
|
151
150
|
it "enqueues the job in the same blocked state as the job group" do
|
152
|
-
Delayed::Job.
|
151
|
+
expect(Delayed::Job).to have_received(:enqueue).with(job, job_group_id: job_group.id, blocked: blocked)
|
153
152
|
end
|
154
153
|
end
|
155
154
|
|
@@ -169,7 +168,7 @@ describe Delayed::JobGroups::JobGroup do
|
|
169
168
|
job_group.unblock
|
170
169
|
end
|
171
170
|
|
172
|
-
its(:blocked?) {
|
171
|
+
its(:blocked?) { is_expected.to be(false) }
|
173
172
|
end
|
174
173
|
|
175
174
|
context "when the JobGroup is blocked" do
|
@@ -184,10 +183,10 @@ describe Delayed::JobGroups::JobGroup do
|
|
184
183
|
Timecop.freeze(unblock_time) { job_group.unblock }
|
185
184
|
end
|
186
185
|
|
187
|
-
its(:blocked?) {
|
186
|
+
its(:blocked?) { is_expected.to be(false) }
|
188
187
|
|
189
188
|
it "sets the job's run_at to the unblocked time" do
|
190
|
-
job.reload.run_at.
|
189
|
+
expect(job.reload.run_at).to eq unblock_time
|
191
190
|
end
|
192
191
|
|
193
192
|
it_behaves_like "the job group was not completed"
|
@@ -199,7 +198,7 @@ describe Delayed::JobGroups::JobGroup do
|
|
199
198
|
job_group.unblock
|
200
199
|
end
|
201
200
|
|
202
|
-
its(:blocked?) {
|
201
|
+
its(:blocked?) { is_expected.to be(false) }
|
203
202
|
it_behaves_like "the job group was completed"
|
204
203
|
end
|
205
204
|
end
|
@@ -214,15 +213,15 @@ describe Delayed::JobGroups::JobGroup do
|
|
214
213
|
end
|
215
214
|
|
216
215
|
it "destroys the job group" do
|
217
|
-
job_group.
|
216
|
+
expect(job_group).to have_been_destroyed
|
218
217
|
end
|
219
218
|
|
220
219
|
it "destroys queued jobs" do
|
221
|
-
queued_job.
|
220
|
+
expect(queued_job).to have_been_destroyed
|
222
221
|
end
|
223
222
|
|
224
223
|
it "does not destroy running jobs" do
|
225
|
-
running_job.
|
224
|
+
expect(running_job).not_to have_been_destroyed
|
226
225
|
end
|
227
226
|
end
|
228
227
|
|
@@ -1,77 +1,72 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
3
|
describe Delayed::JobGroups::Plugin do
|
6
|
-
|
7
|
-
before(:all) do
|
4
|
+
before do
|
8
5
|
@old_max_attempts = Delayed::Worker.max_attempts
|
9
6
|
Delayed::Worker.max_attempts = 2
|
10
|
-
end
|
11
7
|
|
12
|
-
after(:all) do
|
13
|
-
Delayed::Worker.max_attempts = @old_max_attempts
|
14
|
-
end
|
15
|
-
|
16
|
-
before(:each) do
|
17
8
|
CompletionJob.invoked = false
|
18
9
|
CancellationJob.invoked = false
|
19
10
|
end
|
20
11
|
|
12
|
+
after do
|
13
|
+
Delayed::Worker.max_attempts = @old_max_attempts
|
14
|
+
end
|
15
|
+
|
21
16
|
let!(:job_group) { Delayed::JobGroups::JobGroup.create!(on_completion_job: CompletionJob.new) }
|
22
17
|
|
23
18
|
it "runs the completion job after completing other jobs" do
|
24
19
|
job_group.enqueue(NoOpJob.new)
|
25
20
|
job_group.enqueue(NoOpJob.new)
|
26
21
|
job_group.mark_queueing_complete
|
27
|
-
job_group_count.
|
28
|
-
queued_job_count.
|
22
|
+
expect(job_group_count).to eq 1
|
23
|
+
expect(queued_job_count).to eq 2
|
29
24
|
|
30
25
|
# Run our first job
|
31
26
|
Delayed::Worker.new.work_off(1)
|
32
|
-
CompletionJob.invoked.
|
33
|
-
job_group_count.
|
34
|
-
queued_job_count.
|
27
|
+
expect(CompletionJob.invoked).to be(false)
|
28
|
+
expect(job_group_count).to eq 1
|
29
|
+
expect(queued_job_count).to eq 1
|
35
30
|
|
36
31
|
# Run our second job which should enqueue the completion job
|
37
32
|
Delayed::Worker.new.work_off(1)
|
38
|
-
CompletionJob.invoked.
|
39
|
-
job_group_count.
|
40
|
-
queued_job_count.
|
33
|
+
expect(CompletionJob.invoked).to be(false)
|
34
|
+
expect(job_group_count).to eq 0
|
35
|
+
expect(queued_job_count).to eq 1
|
41
36
|
|
42
37
|
# Now we should run the completion job
|
43
38
|
Delayed::Worker.new.work_off(1)
|
44
|
-
CompletionJob.invoked.
|
45
|
-
queued_job_count.
|
39
|
+
expect(CompletionJob.invoked).to be(true)
|
40
|
+
expect(queued_job_count).to eq 0
|
46
41
|
end
|
47
42
|
|
48
43
|
it "only runs the completion job after queueing is completed" do
|
49
44
|
job_group.enqueue(NoOpJob.new)
|
50
45
|
job_group.enqueue(NoOpJob.new)
|
51
|
-
job_group_count.
|
52
|
-
queued_job_count.
|
46
|
+
expect(job_group_count).to eq 1
|
47
|
+
expect(queued_job_count).to eq 2
|
53
48
|
|
54
49
|
# Run our first job
|
55
50
|
Delayed::Worker.new.work_off(1)
|
56
|
-
CompletionJob.invoked.
|
57
|
-
job_group_count.
|
58
|
-
queued_job_count.
|
51
|
+
expect(CompletionJob.invoked).to be(false)
|
52
|
+
expect(job_group_count).to eq 1
|
53
|
+
expect(queued_job_count).to eq 1
|
59
54
|
|
60
55
|
# Run our second job
|
61
56
|
Delayed::Worker.new.work_off(1)
|
62
|
-
CompletionJob.invoked.
|
63
|
-
job_group_count.
|
64
|
-
queued_job_count.
|
57
|
+
expect(CompletionJob.invoked).to be(false)
|
58
|
+
expect(job_group_count).to eq 1
|
59
|
+
expect(queued_job_count).to eq 0
|
65
60
|
|
66
61
|
# Mark queueing complete which should queue the completion job
|
67
62
|
job_group.mark_queueing_complete
|
68
|
-
job_group_count.
|
69
|
-
queued_job_count.
|
63
|
+
expect(job_group_count).to eq 0
|
64
|
+
expect(queued_job_count).to eq 1
|
70
65
|
|
71
66
|
# Now we should run the completion job
|
72
67
|
Delayed::Worker.new.work_off(1)
|
73
|
-
CompletionJob.invoked.
|
74
|
-
queued_job_count.
|
68
|
+
expect(CompletionJob.invoked).to be(true)
|
69
|
+
expect(queued_job_count).to eq 0
|
75
70
|
end
|
76
71
|
|
77
72
|
describe "job failures" do
|
@@ -83,15 +78,15 @@ describe Delayed::JobGroups::Plugin do
|
|
83
78
|
job_group.enqueue(FailingJob.new)
|
84
79
|
job_group.enqueue(NoOpJob.new)
|
85
80
|
job_group.mark_queueing_complete
|
86
|
-
queued_job_count.
|
87
|
-
job_group_count.
|
81
|
+
expect(queued_job_count).to eq 2
|
82
|
+
expect(job_group_count).to eq 1
|
88
83
|
|
89
84
|
# Run the job which should fail and cancel the JobGroup
|
90
85
|
Delayed::Worker.new.work_off(1)
|
91
|
-
CompletionJob.invoked.
|
92
|
-
failed_job_count.
|
93
|
-
queued_job_count.
|
94
|
-
job_group_count.
|
86
|
+
expect(CompletionJob.invoked).to be(false)
|
87
|
+
expect(failed_job_count).to eq 1
|
88
|
+
expect(queued_job_count).to eq 0
|
89
|
+
expect(job_group_count).to eq 0
|
95
90
|
end
|
96
91
|
end
|
97
92
|
|
@@ -105,15 +100,15 @@ describe Delayed::JobGroups::Plugin do
|
|
105
100
|
job_group.enqueue(FailingJob.new)
|
106
101
|
job_group.enqueue(NoOpJob.new)
|
107
102
|
job_group.mark_queueing_complete
|
108
|
-
queued_job_count.
|
109
|
-
job_group_count.
|
103
|
+
expect(queued_job_count).to eq 2
|
104
|
+
expect(job_group_count).to eq 1
|
110
105
|
|
111
106
|
# Run the job which should fail don't cancel the JobGroup
|
112
107
|
Delayed::Worker.new.work_off(1)
|
113
|
-
CancellationJob.invoked.
|
114
|
-
failed_job_count.
|
115
|
-
queued_job_count.
|
116
|
-
job_group_count.
|
108
|
+
expect(CancellationJob.invoked).to be(false)
|
109
|
+
expect(failed_job_count).to eq 1
|
110
|
+
expect(queued_job_count).to eq 1
|
111
|
+
expect(job_group_count).to eq 1
|
117
112
|
end
|
118
113
|
end
|
119
114
|
end
|
@@ -121,12 +116,12 @@ describe Delayed::JobGroups::Plugin do
|
|
121
116
|
it "doesn't retry failed jobs if the job group has been canceled" do
|
122
117
|
job_group.cancel
|
123
118
|
Delayed::Job.enqueue(FailingJob.new, job_group_id: job_group.id)
|
124
|
-
queued_job_count.
|
119
|
+
expect(queued_job_count).to eq 1
|
125
120
|
|
126
121
|
# Run the job which should fail and should not queue a retry
|
127
122
|
Delayed::Worker.new.work_off(1)
|
128
|
-
failed_job_count.
|
129
|
-
queued_job_count.
|
123
|
+
expect(failed_job_count).to eq 1
|
124
|
+
expect(queued_job_count).to eq 0
|
130
125
|
end
|
131
126
|
|
132
127
|
it "doesn't run jobs until they're unblocked" do
|
@@ -136,32 +131,32 @@ describe Delayed::JobGroups::Plugin do
|
|
136
131
|
job_group.enqueue(NoOpJob.new)
|
137
132
|
job_group.enqueue(NoOpJob.new)
|
138
133
|
job_group.mark_queueing_complete
|
139
|
-
Delayed::Job.count.
|
134
|
+
expect(Delayed::Job.count).to eq 2
|
140
135
|
|
141
136
|
# No jobs should run because they're blocked
|
142
137
|
(successes, failures) = Delayed::Worker.new.work_off
|
143
|
-
successes.
|
144
|
-
failures.
|
145
|
-
Delayed::Job.count.
|
138
|
+
expect(successes).to eq 0
|
139
|
+
expect(failures).to eq 0
|
140
|
+
expect(Delayed::Job.count).to eq 2
|
146
141
|
|
147
142
|
job_group.unblock
|
148
143
|
|
149
144
|
# Run our first job
|
150
145
|
Delayed::Worker.new.work_off(1)
|
151
|
-
CompletionJob.invoked.
|
152
|
-
job_group_count.
|
153
|
-
Delayed::Job.count.
|
146
|
+
expect(CompletionJob.invoked).to be(false)
|
147
|
+
expect(job_group_count).to eq 1
|
148
|
+
expect(Delayed::Job.count).to eq 1
|
154
149
|
|
155
150
|
# Run our second job which should enqueue the completion job
|
156
151
|
Delayed::Worker.new.work_off(1)
|
157
|
-
CompletionJob.invoked.
|
158
|
-
job_group_count.
|
159
|
-
Delayed::Job.count.
|
152
|
+
expect(CompletionJob.invoked).to be(false)
|
153
|
+
expect(job_group_count).to eq 0
|
154
|
+
expect(Delayed::Job.count).to eq 1
|
160
155
|
|
161
156
|
# Now we should run the completion job
|
162
157
|
Delayed::Worker.new.work_off(1)
|
163
|
-
CompletionJob.invoked.
|
164
|
-
Delayed::Job.count.
|
158
|
+
expect(CompletionJob.invoked).to be(true)
|
159
|
+
expect(Delayed::Job.count).to eq 0
|
165
160
|
end
|
166
161
|
|
167
162
|
context "when a cancellation job is provided" do
|
@@ -176,23 +171,23 @@ describe Delayed::JobGroups::Plugin do
|
|
176
171
|
job_group.enqueue(FailingJob.new)
|
177
172
|
job_group.enqueue(NoOpJob.new)
|
178
173
|
job_group.mark_queueing_complete
|
179
|
-
queued_job_count.
|
180
|
-
job_group_count.
|
174
|
+
expect(queued_job_count).to eq 2
|
175
|
+
expect(job_group_count).to eq 1
|
181
176
|
|
182
177
|
# Run the job which should fail and cancel the JobGroup
|
183
178
|
Delayed::Worker.new.work_off(1)
|
184
|
-
CompletionJob.invoked.
|
185
|
-
CancellationJob.invoked.
|
186
|
-
failed_job_count.
|
179
|
+
expect(CompletionJob.invoked).to be(false)
|
180
|
+
expect(CancellationJob.invoked).to be(false)
|
181
|
+
expect(failed_job_count).to eq 1
|
187
182
|
|
188
|
-
queued_job_count.
|
189
|
-
job_group_count.
|
183
|
+
expect(queued_job_count).to eq 1
|
184
|
+
expect(job_group_count).to eq 0
|
190
185
|
|
191
186
|
# Now we should run the cancellation job
|
192
187
|
Delayed::Worker.new.work_off(1)
|
193
|
-
CompletionJob.invoked.
|
194
|
-
CancellationJob.invoked.
|
195
|
-
queued_job_count.
|
188
|
+
expect(CompletionJob.invoked).to be(false)
|
189
|
+
expect(CancellationJob.invoked).to be(true)
|
190
|
+
expect(queued_job_count).to eq 0
|
196
191
|
end
|
197
192
|
|
198
193
|
it "runs the cancellation job after the job group is cancelled" do
|
@@ -201,14 +196,14 @@ describe Delayed::JobGroups::Plugin do
|
|
201
196
|
job_group.mark_queueing_complete
|
202
197
|
job_group.cancel
|
203
198
|
|
204
|
-
#cancellation job should be queued
|
205
|
-
queued_job_count.
|
206
|
-
CancellationJob.invoked.
|
199
|
+
# cancellation job should be queued
|
200
|
+
expect(queued_job_count).to eq 1
|
201
|
+
expect(CancellationJob.invoked).to be(false)
|
207
202
|
|
208
203
|
# Run the cancellation job
|
209
204
|
Delayed::Worker.new.work_off(1)
|
210
|
-
CancellationJob.invoked.
|
211
|
-
queued_job_count.
|
205
|
+
expect(CancellationJob.invoked).to be(true)
|
206
|
+
expect(queued_job_count).to eq 0
|
212
207
|
end
|
213
208
|
end
|
214
209
|
|
@@ -219,21 +214,21 @@ describe Delayed::JobGroups::Plugin do
|
|
219
214
|
job_group.enqueue(NoOpJob.new)
|
220
215
|
job_group.enqueue(NoOpJob.new)
|
221
216
|
job_group.mark_queueing_complete
|
222
|
-
job_group_count.
|
223
|
-
queued_job_count.
|
224
|
-
failed_job_count.
|
217
|
+
expect(job_group_count).to eq 1
|
218
|
+
expect(queued_job_count).to eq 2
|
219
|
+
expect(failed_job_count).to eq 0
|
225
220
|
|
226
221
|
# Run our first job
|
227
222
|
Delayed::Worker.new.work_off(1)
|
228
|
-
job_group_count.
|
229
|
-
queued_job_count.
|
230
|
-
failed_job_count.
|
223
|
+
expect(job_group_count).to eq 1
|
224
|
+
expect(queued_job_count).to eq 1
|
225
|
+
expect(failed_job_count).to eq 0
|
231
226
|
|
232
227
|
# Run our second job which should delete the job group
|
233
228
|
Delayed::Worker.new.work_off(1)
|
234
|
-
job_group_count.
|
235
|
-
queued_job_count.
|
236
|
-
failed_job_count.
|
229
|
+
expect(job_group_count).to eq 0
|
230
|
+
expect(queued_job_count).to eq 0
|
231
|
+
expect(failed_job_count).to eq 0
|
237
232
|
end
|
238
233
|
end
|
239
234
|
|