inst-jobs 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrate/20101216224513_create_delayed_jobs.rb +9 -7
  3. data/db/migrate/20110531144916_cleanup_delayed_jobs_indexes.rb +8 -13
  4. data/db/migrate/20110610213249_optimize_delayed_jobs.rb +8 -8
  5. data/db/migrate/20110831210257_add_delayed_jobs_next_in_strand.rb +25 -25
  6. data/db/migrate/20120510004759_delayed_jobs_delete_trigger_lock_for_update.rb +4 -8
  7. data/db/migrate/20120531150712_drop_psql_jobs_pop_fn.rb +1 -3
  8. data/db/migrate/20120607164022_delayed_jobs_use_advisory_locks.rb +11 -15
  9. data/db/migrate/20120607181141_index_jobs_on_locked_by.rb +1 -1
  10. data/db/migrate/20120608191051_add_jobs_run_at_index.rb +2 -2
  11. data/db/migrate/20120927184213_change_delayed_jobs_handler_to_text.rb +1 -1
  12. data/db/migrate/20140505215510_copy_failed_jobs_original_id.rb +2 -3
  13. data/db/migrate/20150807133223_add_max_concurrent_to_jobs.rb +9 -13
  14. data/db/migrate/20151210162949_improve_max_concurrent.rb +4 -8
  15. data/db/migrate/20161206323555_add_back_default_string_limits_jobs.rb +3 -2
  16. data/db/migrate/20181217155351_speed_up_max_concurrent_triggers.rb +13 -17
  17. data/db/migrate/20200330230722_add_id_to_get_delayed_jobs_index.rb +8 -8
  18. data/db/migrate/20200824222232_speed_up_max_concurrent_delete_trigger.rb +72 -77
  19. data/db/migrate/20200825011002_add_strand_order_override.rb +93 -97
  20. data/db/migrate/20210809145804_add_n_strand_index.rb +12 -0
  21. data/db/migrate/20210812210128_add_singleton_column.rb +200 -0
  22. data/db/migrate/20210917232626_add_delete_conflicting_singletons_before_unlock_trigger.rb +27 -0
  23. data/db/migrate/20210928174754_fix_singleton_condition_in_before_insert.rb +56 -0
  24. data/db/migrate/20210929204903_update_conflicting_singleton_function_to_use_index.rb +27 -0
  25. data/exe/inst_jobs +3 -2
  26. data/lib/delayed/backend/active_record.rb +211 -168
  27. data/lib/delayed/backend/base.rb +110 -72
  28. data/lib/delayed/batch.rb +11 -9
  29. data/lib/delayed/cli.rb +98 -84
  30. data/lib/delayed/core_ext/kernel.rb +4 -2
  31. data/lib/delayed/daemon.rb +70 -74
  32. data/lib/delayed/job_tracking.rb +26 -25
  33. data/lib/delayed/lifecycle.rb +27 -23
  34. data/lib/delayed/log_tailer.rb +17 -17
  35. data/lib/delayed/logging.rb +13 -16
  36. data/lib/delayed/message_sending.rb +43 -52
  37. data/lib/delayed/performable_method.rb +6 -8
  38. data/lib/delayed/periodic.rb +72 -68
  39. data/lib/delayed/plugin.rb +2 -4
  40. data/lib/delayed/pool.rb +205 -168
  41. data/lib/delayed/server/helpers.rb +6 -6
  42. data/lib/delayed/server.rb +51 -54
  43. data/lib/delayed/settings.rb +94 -81
  44. data/lib/delayed/testing.rb +21 -22
  45. data/lib/delayed/version.rb +1 -1
  46. data/lib/delayed/work_queue/in_process.rb +21 -17
  47. data/lib/delayed/work_queue/parent_process/client.rb +55 -53
  48. data/lib/delayed/work_queue/parent_process/server.rb +245 -207
  49. data/lib/delayed/work_queue/parent_process.rb +52 -53
  50. data/lib/delayed/worker/consul_health_check.rb +32 -33
  51. data/lib/delayed/worker/health_check.rb +34 -26
  52. data/lib/delayed/worker/null_health_check.rb +3 -1
  53. data/lib/delayed/worker/process_helper.rb +8 -9
  54. data/lib/delayed/worker.rb +272 -241
  55. data/lib/delayed/yaml_extensions.rb +12 -10
  56. data/lib/delayed_job.rb +37 -37
  57. data/lib/inst-jobs.rb +1 -1
  58. data/spec/active_record_job_spec.rb +143 -139
  59. data/spec/delayed/cli_spec.rb +7 -7
  60. data/spec/delayed/daemon_spec.rb +10 -9
  61. data/spec/delayed/message_sending_spec.rb +16 -9
  62. data/spec/delayed/periodic_spec.rb +14 -21
  63. data/spec/delayed/server_spec.rb +38 -38
  64. data/spec/delayed/settings_spec.rb +26 -25
  65. data/spec/delayed/work_queue/in_process_spec.rb +7 -8
  66. data/spec/delayed/work_queue/parent_process/client_spec.rb +17 -12
  67. data/spec/delayed/work_queue/parent_process/server_spec.rb +117 -41
  68. data/spec/delayed/work_queue/parent_process_spec.rb +21 -23
  69. data/spec/delayed/worker/consul_health_check_spec.rb +37 -50
  70. data/spec/delayed/worker/health_check_spec.rb +60 -52
  71. data/spec/delayed/worker_spec.rb +44 -21
  72. data/spec/sample_jobs.rb +45 -15
  73. data/spec/shared/delayed_batch.rb +74 -67
  74. data/spec/shared/delayed_method.rb +143 -102
  75. data/spec/shared/performable_method.rb +39 -38
  76. data/spec/shared/shared_backend.rb +550 -437
  77. data/spec/shared/testing.rb +14 -14
  78. data/spec/shared/worker.rb +156 -148
  79. data/spec/shared_jobs_specs.rb +13 -13
  80. data/spec/spec_helper.rb +53 -55
  81. metadata +148 -82
  82. data/lib/delayed/backend/redis/bulk_update.lua +0 -50
  83. data/lib/delayed/backend/redis/destroy_job.lua +0 -2
  84. data/lib/delayed/backend/redis/enqueue.lua +0 -29
  85. data/lib/delayed/backend/redis/fail_job.lua +0 -5
  86. data/lib/delayed/backend/redis/find_available.lua +0 -3
  87. data/lib/delayed/backend/redis/functions.rb +0 -59
  88. data/lib/delayed/backend/redis/get_and_lock_next_available.lua +0 -17
  89. data/lib/delayed/backend/redis/includes/jobs_common.lua +0 -203
  90. data/lib/delayed/backend/redis/job.rb +0 -535
  91. data/lib/delayed/backend/redis/set_running.lua +0 -5
  92. data/lib/delayed/backend/redis/tickle_strand.lua +0 -2
  93. data/spec/gemfiles/42.gemfile +0 -7
  94. data/spec/gemfiles/50.gemfile +0 -7
  95. data/spec/gemfiles/51.gemfile +0 -7
  96. data/spec/gemfiles/52.gemfile +0 -7
  97. data/spec/gemfiles/60.gemfile +0 -7
  98. data/spec/redis_job_spec.rb +0 -148
@@ -1,220 +1,225 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- shared_examples_for 'a backend' do
3
+ module InDelayedJobTest
4
+ def self.check_in_job
5
+ Delayed::Job.in_delayed_job?.should == true
6
+ end
7
+ end
8
+
9
+ shared_examples_for "a backend" do
4
10
  def create_job(opts = {})
5
- Delayed::Job.enqueue(SimpleJob.new, **{ :queue => nil }.merge(opts))
11
+ Delayed::Job.enqueue(SimpleJob.new, **{ queue: nil }.merge(opts))
6
12
  end
7
13
 
8
14
  before do
9
15
  SimpleJob.runs = 0
10
16
  end
11
17
 
12
- it "should set run_at automatically if not set" do
13
- Delayed::Job.create(:payload_object => ErrorJob.new).run_at.should_not be_nil
18
+ it "sets run_at automatically if not set" do
19
+ expect(Delayed::Job.create(payload_object: ErrorJob.new).run_at).not_to be_nil
14
20
  end
15
21
 
16
- it "should not set run_at automatically if already set" do
22
+ it "does not set run_at automatically if already set" do
17
23
  later = Delayed::Job.db_time_now + 5.minutes
18
- Delayed::Job.create(:payload_object => ErrorJob.new, :run_at => later).run_at.should be_within(1).of(later)
24
+ expect(Delayed::Job.create(payload_object: ErrorJob.new, run_at: later).run_at).to be_within(1).of(later)
19
25
  end
20
26
 
21
- it "should raise ArgumentError when handler doesn't respond_to :perform" do
22
- lambda { Delayed::Job.enqueue(Object.new) }.should raise_error(ArgumentError)
27
+ it "raises ArgumentError when handler doesn't respond_to :perform" do
28
+ expect { Delayed::Job.enqueue(Object.new) }.to raise_error(ArgumentError)
23
29
  end
24
30
 
25
- it "should increase count after enqueuing items" do
31
+ it "increases count after enqueuing items" do
26
32
  Delayed::Job.enqueue SimpleJob.new
27
- Delayed::Job.jobs_count(:current).should == 1
33
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
28
34
  end
29
35
 
30
- it "should be able to set priority when enqueuing items" do
31
- @job = Delayed::Job.enqueue SimpleJob.new, :priority => 5
32
- @job.priority.should == 5
36
+ it "is able to set priority when enqueuing items" do
37
+ @job = Delayed::Job.enqueue SimpleJob.new, priority: 5
38
+ expect(@job.priority).to eq(5)
33
39
  end
34
40
 
35
- it "should use the default priority when enqueuing items" do
41
+ it "uses the default priority when enqueuing items" do
36
42
  Delayed::Job.default_priority = 0
37
43
  @job = Delayed::Job.enqueue SimpleJob.new
38
- @job.priority.should == 0
44
+ expect(@job.priority).to eq(0)
39
45
  Delayed::Job.default_priority = 10
40
46
  @job = Delayed::Job.enqueue SimpleJob.new
41
- @job.priority.should == 10
47
+ expect(@job.priority).to eq(10)
42
48
  Delayed::Job.default_priority = 0
43
49
  end
44
50
 
45
- it "should be able to set run_at when enqueuing items" do
51
+ it "is able to set run_at when enqueuing items" do
46
52
  later = Delayed::Job.db_time_now + 5.minutes
47
- @job = Delayed::Job.enqueue SimpleJob.new, :priority => 5, :run_at => later
48
- @job.run_at.should be_within(1).of(later)
53
+ @job = Delayed::Job.enqueue SimpleJob.new, priority: 5, run_at: later
54
+ expect(@job.run_at).to be_within(1).of(later)
49
55
  end
50
56
 
51
- it "should be able to set expires_at when enqueuing items" do
57
+ it "is able to set expires_at when enqueuing items" do
52
58
  later = Delayed::Job.db_time_now + 1.day
53
- @job = Delayed::Job.enqueue SimpleJob.new, :expires_at => later
54
- @job.expires_at.should be_within(1).of(later)
59
+ @job = Delayed::Job.enqueue SimpleJob.new, expires_at: later
60
+ expect(@job.expires_at).to be_within(1).of(later)
55
61
  end
56
62
 
57
- it "should work with jobs in modules" do
63
+ it "works with jobs in modules" do
58
64
  M::ModuleJob.runs = 0
59
65
  job = Delayed::Job.enqueue M::ModuleJob.new
60
- lambda { job.invoke_job }.should change { M::ModuleJob.runs }.from(0).to(1)
66
+ expect { job.invoke_job }.to change { M::ModuleJob.runs }.from(0).to(1)
61
67
  end
62
68
 
63
- it "should raise an DeserializationError when the job class is totally unknown" do
64
- job = Delayed::Job.new :handler => "--- !ruby/object:JobThatDoesNotExist {}"
65
- lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError)
69
+ it "raises an DeserializationError when the job class is totally unknown" do
70
+ job = Delayed::Job.new handler: "--- !ruby/object:JobThatDoesNotExist {}"
71
+ expect { job.payload_object.perform }.to raise_error(Delayed::Backend::DeserializationError)
66
72
  end
67
73
 
68
- it "should try to load the class when it is unknown at the time of the deserialization" do
69
- job = Delayed::Job.new :handler => "--- !ruby/object:JobThatDoesNotExist {}"
70
- lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError)
74
+ it "tries to load the class when it is unknown at the time of the deserialization" do
75
+ job = Delayed::Job.new handler: "--- !ruby/object:JobThatDoesNotExist {}"
76
+ expect { job.payload_object.perform }.to raise_error(Delayed::Backend::DeserializationError)
71
77
  end
72
78
 
73
- it "should try include the namespace when loading unknown objects" do
74
- job = Delayed::Job.new :handler => "--- !ruby/object:Delayed::JobThatDoesNotExist {}"
75
- lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError)
79
+ it "tries include the namespace when loading unknown objects" do
80
+ job = Delayed::Job.new handler: "--- !ruby/object:Delayed::JobThatDoesNotExist {}"
81
+ expect { job.payload_object.perform }.to raise_error(Delayed::Backend::DeserializationError)
76
82
  end
77
83
 
78
- it "should also try to load structs when they are unknown (raises TypeError)" do
79
- job = Delayed::Job.new :handler => "--- !ruby/struct:JobThatDoesNotExist {}"
80
- lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError)
84
+ it "alsoes try to load structs when they are unknown (raises TypeError)" do
85
+ job = Delayed::Job.new handler: "--- !ruby/struct:JobThatDoesNotExist {}"
86
+ expect { job.payload_object.perform }.to raise_error(Delayed::Backend::DeserializationError)
81
87
  end
82
88
 
83
- it "should try include the namespace when loading unknown structs" do
84
- job = Delayed::Job.new :handler => "--- !ruby/struct:Delayed::JobThatDoesNotExist {}"
85
- lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError)
89
+ it "tries include the namespace when loading unknown structs" do
90
+ job = Delayed::Job.new handler: "--- !ruby/struct:Delayed::JobThatDoesNotExist {}"
91
+ expect { job.payload_object.perform }.to raise_error(Delayed::Backend::DeserializationError)
86
92
  end
87
93
 
88
- it "should raise an DeserializationError when the handler is invalid YAML" do
89
- job = Delayed::Job.new :handler => %{test: ""11"}
90
- lambda { job.payload_object.perform }.should raise_error(Delayed::Backend::DeserializationError, /parsing error/)
94
+ it "raises an DeserializationError when the handler is invalid YAML" do
95
+ job = Delayed::Job.new handler: %(test: ""11")
96
+ expect { job.payload_object.perform }.to raise_error(Delayed::Backend::DeserializationError, /parsing error/)
91
97
  end
92
98
 
93
99
  describe "find_available" do
94
- it "should not find failed jobs" do
95
- @job = create_job :attempts => 50
100
+ it "does not find failed jobs" do
101
+ @job = create_job attempts: 50
96
102
  @job.fail!
97
- Delayed::Job.find_available(5).should_not include(@job)
103
+ expect(Delayed::Job.find_available(5)).not_to include(@job)
98
104
  end
99
105
 
100
- it "should not find jobs scheduled for the future" do
101
- @job = create_job :run_at => (Delayed::Job.db_time_now + 1.minute)
102
- Delayed::Job.find_available(5).should_not include(@job)
106
+ it "does not find jobs scheduled for the future" do
107
+ @job = create_job run_at: (Delayed::Job.db_time_now + 1.minute)
108
+ expect(Delayed::Job.find_available(5)).not_to include(@job)
103
109
  end
104
110
 
105
- it "should not find jobs locked by another worker" do
111
+ it "does not find jobs locked by another worker" do
106
112
  @job = create_job
107
- Delayed::Job.get_and_lock_next_available('other_worker').should == @job
108
- Delayed::Job.find_available(5).should_not include(@job)
113
+ expect(Delayed::Job.get_and_lock_next_available("other_worker")).to eq(@job)
114
+ expect(Delayed::Job.find_available(5)).not_to include(@job)
109
115
  end
110
116
 
111
- it "should find open jobs" do
117
+ it "finds open jobs" do
112
118
  @job = create_job
113
- Delayed::Job.find_available(5).should include(@job)
119
+ expect(Delayed::Job.find_available(5)).to include(@job)
114
120
  end
115
121
 
116
122
  it "returns an empty hash when asking for multiple jobs, and there aren't any" do
117
- locked_jobs = Delayed::Job.get_and_lock_next_available(['worker1', 'worker2'])
118
- locked_jobs.should == {}
123
+ locked_jobs = Delayed::Job.get_and_lock_next_available(%w[worker1 worker2])
124
+ expect(locked_jobs).to eq({})
119
125
  end
120
126
  end
121
127
 
122
128
  context "when another worker is already performing an task, it" do
123
-
124
- before :each do
125
- @job = Delayed::Job.create :payload_object => SimpleJob.new
126
- Delayed::Job.get_and_lock_next_available('worker1').should == @job
129
+ before do
130
+ @job = Delayed::Job.create payload_object: SimpleJob.new
131
+ expect(Delayed::Job.get_and_lock_next_available("worker1")).to eq(@job)
127
132
  end
128
133
 
129
- it "should not allow a second worker to get exclusive access" do
130
- Delayed::Job.get_and_lock_next_available('worker2').should be_nil
134
+ it "does not allow a second worker to get exclusive access" do
135
+ expect(Delayed::Job.get_and_lock_next_available("worker2")).to be_nil
131
136
  end
132
137
 
133
- it "should not be found by another worker" do
134
- Delayed::Job.find_available(1).length.should == 0
138
+ it "is not found by another worker" do
139
+ expect(Delayed::Job.find_available(1).length).to eq(0)
135
140
  end
136
141
  end
137
142
 
138
- context "#name" do
139
- it "should be the class name of the job that was enqueued" do
140
- Delayed::Job.create(:payload_object => ErrorJob.new ).name.should == 'ErrorJob'
143
+ describe "#name" do
144
+ it "is the class name of the job that was enqueued" do
145
+ expect(Delayed::Job.create(payload_object: ErrorJob.new).name).to eq("ErrorJob")
141
146
  end
142
147
 
143
- it "should be the method that will be called if its a performable method object" do
148
+ it "is the method that will be called if its a performable method object" do
144
149
  @job = Story.delay(ignore_transaction: true).create
145
- @job.name.should == "Story.create"
150
+ expect(@job.name).to eq("Story.create")
146
151
  end
147
152
 
148
- it "should be the instance method that will be called if its a performable method object" do
149
- @job = Story.create(:text => "...").delay(ignore_transaction: true).save
150
- @job.name.should == 'Story#save'
153
+ it "is the instance method that will be called if its a performable method object" do
154
+ @job = Story.create(text: "...").delay(ignore_transaction: true).save
155
+ expect(@job.name).to eq("Story#save")
151
156
  end
152
157
  end
153
158
 
154
159
  context "worker prioritization" do
155
- it "should fetch jobs ordered by priority" do
156
- 10.times { create_job :priority => rand(10) }
160
+ it "fetches jobs ordered by priority" do
161
+ 10.times { create_job priority: rand(10) }
157
162
  jobs = Delayed::Job.find_available(10)
158
- jobs.size.should == 10
163
+ expect(jobs.size).to eq(10)
159
164
  jobs.each_cons(2) do |a, b|
160
- a.priority.should <= b.priority
165
+ expect(a.priority).to be <= b.priority
161
166
  end
162
167
  end
163
168
 
164
- it "should not find jobs lower than the given priority" do
165
- job1 = create_job :priority => 5
166
- found = Delayed::Job.get_and_lock_next_available('test1', Delayed::Settings.queue, 10, 20)
167
- found.should be_nil
168
- job2 = create_job :priority => 10
169
- found = Delayed::Job.get_and_lock_next_available('test1', Delayed::Settings.queue, 10, 20)
170
- found.should == job2
171
- job3 = create_job :priority => 15
172
- found = Delayed::Job.get_and_lock_next_available('test2', Delayed::Settings.queue, 10, 20)
173
- found.should == job3
169
+ it "does not find jobs lower than the given priority" do
170
+ create_job priority: 5
171
+ found = Delayed::Job.get_and_lock_next_available("test1", Delayed::Settings.queue, 10, 20)
172
+ expect(found).to be_nil
173
+ job2 = create_job priority: 10
174
+ found = Delayed::Job.get_and_lock_next_available("test1", Delayed::Settings.queue, 10, 20)
175
+ expect(found).to eq(job2)
176
+ job3 = create_job priority: 15
177
+ found = Delayed::Job.get_and_lock_next_available("test2", Delayed::Settings.queue, 10, 20)
178
+ expect(found).to eq(job3)
174
179
  end
175
180
 
176
- it "should not find jobs higher than the given priority" do
177
- job1 = create_job :priority => 25
178
- found = Delayed::Job.get_and_lock_next_available('test1', Delayed::Settings.queue, 10, 20)
179
- found.should be_nil
180
- job2 = create_job :priority => 20
181
- found = Delayed::Job.get_and_lock_next_available('test1', Delayed::Settings.queue, 10, 20)
182
- found.should == job2
183
- job3 = create_job :priority => 15
184
- found = Delayed::Job.get_and_lock_next_available('test2', Delayed::Settings.queue, 10, 20)
185
- found.should == job3
181
+ it "does not find jobs higher than the given priority" do
182
+ create_job priority: 25
183
+ found = Delayed::Job.get_and_lock_next_available("test1", Delayed::Settings.queue, 10, 20)
184
+ expect(found).to be_nil
185
+ job2 = create_job priority: 20
186
+ found = Delayed::Job.get_and_lock_next_available("test1", Delayed::Settings.queue, 10, 20)
187
+ expect(found).to eq(job2)
188
+ job3 = create_job priority: 15
189
+ found = Delayed::Job.get_and_lock_next_available("test2", Delayed::Settings.queue, 10, 20)
190
+ expect(found).to eq(job3)
186
191
  end
187
192
  end
188
193
 
189
194
  context "clear_locks!" do
190
195
  before do
191
- @job = create_job(:locked_by => 'worker', :locked_at => Delayed::Job.db_time_now)
196
+ @job = create_job(locked_by: "worker", locked_at: Delayed::Job.db_time_now)
192
197
  end
193
198
 
194
- it "should clear locks for the given worker" do
195
- Delayed::Job.clear_locks!('worker')
196
- Delayed::Job.find_available(5).should include(@job)
199
+ it "clears locks for the given worker" do
200
+ Delayed::Job.clear_locks!("worker")
201
+ expect(Delayed::Job.find_available(5)).to include(@job)
197
202
  end
198
203
 
199
- it "should not clear locks for other workers" do
200
- Delayed::Job.clear_locks!('worker1')
201
- Delayed::Job.find_available(5).should_not include(@job)
204
+ it "does not clear locks for other workers" do
205
+ Delayed::Job.clear_locks!("worker1")
206
+ expect(Delayed::Job.find_available(5)).not_to include(@job)
202
207
  end
203
208
  end
204
209
 
205
210
  context "unlock" do
206
211
  before do
207
- @job = create_job(:locked_by => 'worker', :locked_at => Delayed::Job.db_time_now)
212
+ @job = create_job(locked_by: "worker", locked_at: Delayed::Job.db_time_now)
208
213
  end
209
214
 
210
- it "should clear locks" do
215
+ it "clears locks" do
211
216
  @job.unlock
212
- @job.locked_by.should be_nil
213
- @job.locked_at.should be_nil
217
+ expect(@job.locked_by).to be_nil
218
+ expect(@job.locked_at).to be_nil
214
219
  end
215
220
 
216
221
  it "clears locks from multiple jobs" do
217
- job2 = create_job(:locked_by => 'worker', :locked_at => Delayed::Job.db_time_now)
222
+ job2 = create_job(locked_by: "worker", locked_at: Delayed::Job.db_time_now)
218
223
  Delayed::Job.unlock([@job, job2])
219
224
  expect(@job.locked_at).to be_nil
220
225
  expect(job2.locked_at).to be_nil
@@ -225,295 +230,406 @@ shared_examples_for 'a backend' do
225
230
 
226
231
  describe "#transfer_lock" do
227
232
  it "works" do
228
- job = create_job(:locked_by => 'worker', :locked_at => Delayed::Job.db_time_now)
229
- expect(job.transfer_lock!(from: 'worker', to: 'worker2')).to eq true
230
- expect(Delayed::Job.find(job.id).locked_by).to eq 'worker2'
233
+ job = create_job(locked_by: "worker", locked_at: Delayed::Job.db_time_now)
234
+ expect(job.transfer_lock!(from: "worker", to: "worker2")).to eq true
235
+ expect(Delayed::Job.find(job.id).locked_by).to eq "worker2"
231
236
  end
232
237
  end
233
238
 
234
239
  context "strands" do
235
- it "should run strand jobs in strict order" do
236
- job1 = create_job(:strand => 'myjobs')
237
- job2 = create_job(:strand => 'myjobs')
238
- Delayed::Job.get_and_lock_next_available('w1').should == job1
239
- Delayed::Job.get_and_lock_next_available('w2').should == nil
240
+ it "runs strand jobs in strict order" do
241
+ job1 = create_job(strand: "myjobs")
242
+ job2 = create_job(strand: "myjobs")
243
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
244
+ expect(Delayed::Job.get_and_lock_next_available("w2")).to eq(nil)
240
245
  job1.destroy
241
246
  # update time since the failed lock pushed it forward
242
247
  job2.run_at = 1.minute.ago
243
248
  job2.save!
244
- Delayed::Job.get_and_lock_next_available('w3').should == job2
245
- Delayed::Job.get_and_lock_next_available('w4').should == nil
249
+ expect(Delayed::Job.get_and_lock_next_available("w3")).to eq(job2)
250
+ expect(Delayed::Job.get_and_lock_next_available("w4")).to eq(nil)
246
251
  end
247
252
 
248
- it "should fail to lock if an earlier job gets locked" do
249
- job1 = create_job(:strand => 'myjobs')
250
- job2 = create_job(:strand => 'myjobs')
251
- Delayed::Job.find_available(2).should == [job1]
252
- Delayed::Job.find_available(2).should == [job1]
253
+ it "fails to lock if an earlier job gets locked" do
254
+ job1 = create_job(strand: "myjobs")
255
+ job2 = create_job(strand: "myjobs")
256
+ expect(Delayed::Job.find_available(2)).to eq([job1])
257
+ expect(Delayed::Job.find_available(2)).to eq([job1])
253
258
 
254
259
  # job1 gets locked by w1
255
- Delayed::Job.get_and_lock_next_available('w1').should == job1
260
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
256
261
 
257
262
  # normally w2 would now be able to lock job2, but strands prevent it
258
- Delayed::Job.get_and_lock_next_available('w2').should be_nil
263
+ expect(Delayed::Job.get_and_lock_next_available("w2")).to be_nil
259
264
 
260
265
  # now job1 is done
261
266
  job1.destroy
262
267
  # update time since the failed lock pushed it forward
263
268
  job2.run_at = 1.minute.ago
264
269
  job2.save!
265
- Delayed::Job.get_and_lock_next_available('w2').should == job2
270
+ expect(Delayed::Job.get_and_lock_next_available("w2")).to eq(job2)
266
271
  end
267
272
 
268
- it "should keep strand jobs in order as they are rescheduled" do
269
- job1 = create_job(:strand => 'myjobs')
270
- job2 = create_job(:strand => 'myjobs')
271
- job3 = create_job(:strand => 'myjobs')
272
- Delayed::Job.get_and_lock_next_available('w1').should == job1
273
- Delayed::Job.find_available(1).should == []
273
+ it "keeps strand jobs in order as they are rescheduled" do
274
+ job1 = create_job(strand: "myjobs")
275
+ job2 = create_job(strand: "myjobs")
276
+ job3 = create_job(strand: "myjobs")
277
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
278
+ expect(Delayed::Job.find_available(1)).to eq([])
274
279
  job1.destroy
275
- Delayed::Job.find_available(1).should == [job2]
280
+ expect(Delayed::Job.find_available(1)).to eq([job2])
276
281
  # move job2's time forward
277
282
  job2.run_at = 1.second.ago
278
283
  job2.save!
279
284
  job3.run_at = 5.seconds.ago
280
285
  job3.save!
281
286
  # we should still get job2, not job3
282
- Delayed::Job.get_and_lock_next_available('w1').should == job2
287
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job2)
283
288
  end
284
289
 
285
- it "should allow to run the next job if a failed job is present" do
286
- job1 = create_job(:strand => 'myjobs')
287
- job2 = create_job(:strand => 'myjobs')
290
+ it "allows to run the next job if a failed job is present" do
291
+ job1 = create_job(strand: "myjobs")
292
+ job2 = create_job(strand: "myjobs")
288
293
  job1.fail!
289
- Delayed::Job.get_and_lock_next_available('w1').should == job2
294
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job2)
290
295
  end
291
296
 
292
- it "should not interfere with jobs with no strand" do
293
- jobs = [create_job(:strand => nil), create_job(:strand => 'myjobs')]
294
- locked = [Delayed::Job.get_and_lock_next_available('w1'),
295
- Delayed::Job.get_and_lock_next_available('w2')]
296
- jobs.should =~ locked
297
- Delayed::Job.get_and_lock_next_available('w3').should == nil
297
+ it "does not interfere with jobs with no strand" do
298
+ jobs = [create_job(strand: nil), create_job(strand: "myjobs")]
299
+ locked = [Delayed::Job.get_and_lock_next_available("w1"),
300
+ Delayed::Job.get_and_lock_next_available("w2")]
301
+ expect(jobs).to eq locked
302
+ expect(Delayed::Job.get_and_lock_next_available("w3")).to eq(nil)
298
303
  end
299
304
 
300
- it "should not interfere with jobs in other strands" do
301
- jobs = [create_job(:strand => 'strand1'), create_job(:strand => 'strand2')]
302
- locked = [Delayed::Job.get_and_lock_next_available('w1'),
303
- Delayed::Job.get_and_lock_next_available('w2')]
304
- jobs.should =~ locked
305
- Delayed::Job.get_and_lock_next_available('w3').should == nil
305
+ it "does not interfere with jobs in other strands" do
306
+ jobs = [create_job(strand: "strand1"), create_job(strand: "strand2")]
307
+ locked = [Delayed::Job.get_and_lock_next_available("w1"),
308
+ Delayed::Job.get_and_lock_next_available("w2")]
309
+ expect(jobs).to eq locked
310
+ expect(Delayed::Job.get_and_lock_next_available("w3")).to eq(nil)
306
311
  end
307
312
 
308
- it "should not find next jobs when given no priority" do
309
- jobs = [create_job(:strand => 'strand1'), create_job(:strand => 'strand1')]
310
- first = Delayed::Job.get_and_lock_next_available('w1', Delayed::Settings.queue, nil, nil)
311
- second = Delayed::Job.get_and_lock_next_available('w2', Delayed::Settings.queue, nil, nil)
313
+ it "does not find next jobs when given no priority" do
314
+ jobs = [create_job(strand: "strand1"), create_job(strand: "strand1")]
315
+ first = Delayed::Job.get_and_lock_next_available("w1", Delayed::Settings.queue, nil, nil)
316
+ second = Delayed::Job.get_and_lock_next_available("w2", Delayed::Settings.queue, nil, nil)
312
317
  expect(first).to eq jobs.first
313
318
  expect(second).to eq nil
314
319
  end
315
320
 
316
- context 'singleton' do
317
- it "should create if there's no jobs on the strand" do
318
- @job = create_job(:singleton => 'myjobs')
319
- @job.should be_present
320
- Delayed::Job.get_and_lock_next_available('w1').should == @job
321
+ it "complains if you pass more than one strand-based option" do
322
+ expect { create_job(strand: "a", n_strand: "b") }.to raise_error(ArgumentError)
323
+ end
324
+
325
+ context "singleton" do
326
+ it "creates if there's no jobs on the strand" do
327
+ @job = create_job(singleton: "myjobs")
328
+ expect(@job).to be_present
329
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job)
321
330
  end
322
331
 
323
- it "should create if there's another job on the strand, but it's running" do
324
- @job = create_job(:singleton => 'myjobs')
325
- @job.should be_present
326
- Delayed::Job.get_and_lock_next_available('w1').should == @job
332
+ it "creates if there's another job on the strand, but it's running" do
333
+ @job = create_job(singleton: "myjobs")
334
+ expect(@job).to be_present
335
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job)
327
336
 
328
- @job2 = create_job(:singleton => 'myjobs')
329
- @job.should be_present
330
- @job2.should_not == @job
337
+ @job2 = create_job(singleton: "myjobs")
338
+ expect(@job).to be_present
339
+ expect(@job2).not_to eq(@job)
331
340
  end
332
341
 
333
- it "should not create if there's another non-running job on the strand" do
334
- @job = create_job(:singleton => 'myjobs')
335
- @job.should be_present
342
+ it "does not create if there's another non-running job on the strand" do
343
+ @job = create_job(singleton: "myjobs")
344
+ expect(@job).to be_present
336
345
 
337
- @job2 = create_job(:singleton => 'myjobs')
338
- @job2.should == @job
346
+ @job2 = create_job(singleton: "myjobs")
347
+ expect(@job2).to be_new_record
339
348
  end
340
349
 
341
- it "should not create if there's a job running and one waiting on the strand" do
342
- @job = create_job(:singleton => 'myjobs')
343
- @job.should be_present
344
- Delayed::Job.get_and_lock_next_available('w1').should == @job
350
+ it "does not create if there's a job running and one waiting on the strand" do
351
+ @job = create_job(singleton: "myjobs")
352
+ expect(@job).to be_present
353
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job)
345
354
 
346
- @job2 = create_job(:singleton => 'myjobs')
347
- @job2.should be_present
348
- @job2.should_not == @job
355
+ @job2 = create_job(singleton: "myjobs")
356
+ expect(@job2).to be_present
357
+ expect(@job2).not_to eq(@job)
349
358
 
350
- @job3 = create_job(:singleton => 'myjobs')
351
- @job3.should == @job2
359
+ @job3 = create_job(singleton: "myjobs")
360
+ expect(@job3).to be_new_record
352
361
  end
353
362
 
354
- it "should update existing job if new job is set to run sooner" do
355
- job1 = create_job(singleton: 'myjobs', run_at: 1.hour.from_now)
356
- job2 = create_job(singleton: 'myjobs')
357
- job2.should == job1
363
+ it "updates existing job if new job is set to run sooner" do
364
+ job1 = create_job(singleton: "myjobs", run_at: 1.hour.from_now)
365
+ job2 = create_job(singleton: "myjobs")
366
+ expect(job2).to eq(job1)
358
367
  # it should be scheduled to run immediately
359
- Delayed::Job.get_and_lock_next_available('w1').should == job1
368
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
360
369
  end
361
370
 
362
- it "should update existing job to a later date if requested" do
371
+ it "updates existing job to a later date if requested" do
363
372
  t1 = 1.hour.from_now
364
373
  t2 = 2.hours.from_now
365
- job1 = create_job(singleton: 'myjobs', run_at: t1)
366
- job2 = create_job(singleton: 'myjobs', run_at: t2)
367
- job2.should == job1
368
- job2.run_at.to_i.should == t1.to_i
369
-
370
- job3 = create_job(singleton: 'myjobs', run_at: t2, on_conflict: :overwrite)
371
- job3.should == job1
372
- job3.run_at.to_i.should == t2.to_i
374
+ job1 = create_job(singleton: "myjobs", run_at: t1)
375
+ job2 = create_job(singleton: "myjobs", run_at: t2)
376
+ expect(job2).to be_new_record
377
+
378
+ job3 = create_job(singleton: "myjobs", run_at: t2, on_conflict: :overwrite)
379
+ expect(job3).to eq(job1)
380
+ expect(job3.run_at.to_i).to eq(t2.to_i)
373
381
  end
374
382
 
375
- it "should update existing singleton job handler if requested" do
376
- job1 = Delayed::Job.enqueue(SimpleJob.new, queue: nil, singleton: 'myjobs', on_conflict: :overwrite)
377
- job2 = Delayed::Job.enqueue(ErrorJob.new, queue: nil, singleton: 'myjobs', on_conflict: :overwrite)
378
- job2.should == job1
379
- expect(job2.handler).to include("ErrorJob")
383
+ it "updates existing singleton job handler if requested" do
384
+ job1 = Delayed::Job.enqueue(SimpleJob.new, queue: nil, singleton: "myjobs", on_conflict: :overwrite)
385
+ job2 = Delayed::Job.enqueue(ErrorJob.new, queue: nil, singleton: "myjobs", on_conflict: :overwrite)
386
+ expect(job2).to eq(job1)
387
+ expect(job1.reload.handler).to include("ErrorJob")
380
388
  end
381
389
 
382
- it "does not create even if it's earlier when in loose mode" do
383
- t1 = 1.hour.from_now
384
- job1 = create_job(singleton: 'myjobs', run_at: t1)
385
- job2 = create_job(singleton: 'myjobs', on_conflict: :loose)
386
- job1.should == job2
387
- job2.run_at.to_i.should == t1.to_i
390
+ context "next_in_strand management" do
391
+ it "creates first as true, and second as false, then transitions to second when deleted" do
392
+ @job1 = create_job(singleton: "myjobs")
393
+ Delayed::Job.get_and_lock_next_available("w1")
394
+ @job2 = create_job(singleton: "myjobs")
395
+ expect(@job1.reload.next_in_strand).to eq true
396
+ expect(@job2.reload.next_in_strand).to eq false
397
+
398
+ @job1.destroy
399
+ expect(@job2.reload.next_in_strand).to eq true
400
+ end
401
+
402
+ it "when combined with a strand" do
403
+ job1 = create_job(singleton: "singleton", strand: "strand")
404
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job1
405
+ job2 = create_job(singleton: "singleton", strand: "strand")
406
+ expect(job2).not_to eq job1
407
+ expect(job2).not_to be_new_record
408
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
409
+ job3 = create_job(strand: "strand")
410
+ job4 = create_job(strand: "strand")
411
+ expect(job3.reload).not_to be_next_in_strand
412
+ expect(job4.reload).not_to be_next_in_strand
413
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
414
+ job1.destroy
415
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job2
416
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
417
+ job2.destroy
418
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job3
419
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
420
+ job3.destroy
421
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job4
422
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
423
+ end
424
+
425
+ it "when combined with a small n_strand" do
426
+ allow(Delayed::Settings).to receive(:num_strands).and_return(->(*) { 2 })
427
+
428
+ job1 = create_job(singleton: "singleton", n_strand: "strand")
429
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job1
430
+ job2 = create_job(singleton: "singleton", n_strand: "strand")
431
+ expect(job2).not_to eq job1
432
+ expect(job2).not_to be_new_record
433
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
434
+ job3 = create_job(n_strand: "strand")
435
+ job4 = create_job(n_strand: "strand")
436
+ expect(job3.reload).to be_next_in_strand
437
+ expect(job4.reload).not_to be_next_in_strand
438
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job3
439
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
440
+ # this doesn't unlock job2, even though it's ahead of job4
441
+ job3.destroy
442
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job4
443
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
444
+ job4.destroy
445
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
446
+ job1.destroy
447
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job2
448
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
449
+ end
450
+
451
+ it "when combined with a larger n_strand" do
452
+ allow(Delayed::Settings).to receive(:num_strands).and_return(->(*) { 10 })
453
+
454
+ job1 = create_job(singleton: "singleton", n_strand: "strand")
455
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job1
456
+ job2 = create_job(singleton: "singleton", n_strand: "strand")
457
+ expect(job2).not_to eq job1
458
+ expect(job2).not_to be_new_record
459
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
460
+ job3 = create_job(n_strand: "strand")
461
+ job4 = create_job(n_strand: "strand")
462
+ expect(job3.reload).to be_next_in_strand
463
+ expect(job4.reload).to be_next_in_strand
464
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job3
465
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job4
466
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
467
+ # this doesn't unlock job2
468
+ job3.destroy
469
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
470
+ job4.destroy
471
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
472
+ job1.destroy
473
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job2
474
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
475
+ end
476
+ end
477
+
478
+ context "with on_conflict: loose and strand-inferred-from-singleton" do
479
+ around do |example|
480
+ Delayed::Settings.infer_strand_from_singleton = true
481
+ example.call
482
+ ensure
483
+ Delayed::Settings.infer_strand_from_singleton = false
484
+ end
485
+
486
+ it "does not create if there's another non-running job on the strand" do
487
+ @job = create_job(singleton: "myjobs", on_conflict: :loose)
488
+ expect(@job).to be_present
489
+
490
+ @job2 = create_job(singleton: "myjobs", on_conflict: :loose)
491
+ expect(@job2).to be_new_record
492
+ end
493
+ end
494
+
495
+ context "when unlocking with another singleton pending" do
496
+ it "deletes the pending singleton" do
497
+ @job1 = create_job(singleton: "myjobs", max_attempts: 2)
498
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job1)
499
+
500
+ @job2 = create_job(singleton: "myjobs", max_attempts: 2)
501
+
502
+ @job1.reload.reschedule
503
+ expect { @job1.reload }.not_to raise_error
504
+ expect { @job2.reload }.to raise_error(ActiveRecord::RecordNotFound)
505
+ end
388
506
  end
389
507
  end
390
508
  end
391
509
 
392
510
  context "on hold" do
393
- it "should hold/unhold jobs" do
394
- job1 = create_job()
511
+ it "hold/unholds jobs" do
512
+ job1 = create_job
395
513
  job1.hold!
396
- Delayed::Job.get_and_lock_next_available('w1').should be_nil
514
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
397
515
 
398
516
  job1.unhold!
399
- Delayed::Job.get_and_lock_next_available('w1').should == job1
517
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
400
518
  end
401
519
  end
402
520
 
403
521
  context "periodic jobs" do
404
- before(:each) do
522
+ before do
405
523
  # make the periodic job get scheduled in the past
406
524
  @cron_time = 10.minutes.ago
407
525
  allow(Delayed::Periodic).to receive(:now).and_return(@cron_time)
408
526
  Delayed::Periodic.scheduled = {}
409
- Delayed::Periodic.cron('my SimpleJob', '*/5 * * * * *') do
527
+ Delayed::Periodic.cron("my SimpleJob", "*/5 * * * * *") do
410
528
  Delayed::Job.enqueue(SimpleJob.new)
411
529
  end
412
530
  end
413
531
 
414
- it "should schedule jobs if they aren't scheduled yet" do
415
- Delayed::Job.jobs_count(:current).should == 0
532
+ it "schedules jobs if they aren't scheduled yet" do
533
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
416
534
  Delayed::Periodic.perform_audit!
417
- Delayed::Job.jobs_count(:current).should == 1
418
- job = Delayed::Job.get_and_lock_next_available('test1')
419
- job.tag.should == 'periodic: my SimpleJob'
420
- job.payload_object.should == Delayed::Periodic.scheduled['my SimpleJob']
421
- job.run_at.should >= @cron_time
422
- job.run_at.should <= @cron_time + 6.minutes
423
- job.strand.should == job.tag
535
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
536
+ job = Delayed::Job.get_and_lock_next_available("test1")
537
+ expect(job.tag).to eq("periodic: my SimpleJob")
538
+ expect(job.payload_object).to eq(Delayed::Periodic.scheduled["my SimpleJob"])
539
+ expect(job.run_at).to be >= @cron_time
540
+ expect(job.run_at).to be <= @cron_time + 6.minutes
541
+ expect(job.singleton).to eq(job.tag)
424
542
  end
425
543
 
426
- it "should schedule jobs if there are only failed jobs on the queue" do
427
- Delayed::Job.jobs_count(:current).should == 0
544
+ it "schedules jobs if there are only failed jobs on the queue" do
545
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
428
546
  expect { Delayed::Periodic.perform_audit! }.to change { Delayed::Job.jobs_count(:current) }.by(1)
429
- Delayed::Job.jobs_count(:current).should == 1
430
- job = Delayed::Job.get_and_lock_next_available('test1')
547
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
548
+ job = Delayed::Job.get_and_lock_next_available("test1")
431
549
  job.fail!
432
- expect { Delayed::Periodic.perform_audit! }.to change{ Delayed::Job.jobs_count(:current) }.by(1)
550
+ expect { Delayed::Periodic.perform_audit! }.to change { Delayed::Job.jobs_count(:current) }.by(1)
433
551
  end
434
552
 
435
- it "should not schedule jobs that are already scheduled" do
436
- Delayed::Job.jobs_count(:current).should == 0
553
+ it "does not schedule jobs that are already scheduled" do
554
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
437
555
  Delayed::Periodic.perform_audit!
438
- Delayed::Job.jobs_count(:current).should == 1
556
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
439
557
  job = Delayed::Job.find_available(1).first
440
558
  Delayed::Periodic.perform_audit!
441
- Delayed::Job.jobs_count(:current).should == 1
559
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
442
560
  # verify that the same job still exists, it wasn't just replaced with a new one
443
- job.should == Delayed::Job.find_available(1).first
561
+ expect(job).to eq(Delayed::Job.find_available(1).first)
444
562
  end
445
563
 
446
- it "should schedule the next job run after performing" do
447
- Delayed::Job.jobs_count(:current).should == 0
564
+ it "schedules the next job run after performing" do
565
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
448
566
  Delayed::Periodic.perform_audit!
449
- Delayed::Job.jobs_count(:current).should == 1
450
- job = Delayed::Job.get_and_lock_next_available('test')
567
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
568
+ job = Delayed::Job.get_and_lock_next_available("test")
451
569
  run_job(job)
452
570
 
453
- job = Delayed::Job.get_and_lock_next_available('test1')
454
- job.tag.should == 'SimpleJob#perform'
571
+ job = Delayed::Job.get_and_lock_next_available("test1")
572
+ expect(job.tag).to eq("SimpleJob#perform")
455
573
 
456
- next_scheduled = Delayed::Job.get_and_lock_next_available('test2')
457
- next_scheduled.tag.should == 'periodic: my SimpleJob'
458
- next_scheduled.payload_object.should be_is_a(Delayed::Periodic)
574
+ next_scheduled = Delayed::Job.get_and_lock_next_available("test2")
575
+ expect(next_scheduled.tag).to eq("periodic: my SimpleJob")
576
+ expect(next_scheduled.payload_object).to be_is_a(Delayed::Periodic)
459
577
  end
460
578
 
461
- it "should reject duplicate named jobs" do
462
- proc { Delayed::Periodic.cron('my SimpleJob', '*/15 * * * * *') {} }.should raise_error(ArgumentError)
579
+ it "rejects duplicate named jobs" do
580
+ expect { Delayed::Periodic.cron("my SimpleJob", "*/15 * * * * *") { nil } }.to raise_error(ArgumentError)
463
581
  end
464
582
 
465
- it "should handle jobs that are no longer scheduled" do
583
+ it "handles jobs that are no longer scheduled" do
466
584
  Delayed::Periodic.perform_audit!
467
585
  Delayed::Periodic.scheduled = {}
468
- job = Delayed::Job.get_and_lock_next_available('test')
586
+ job = Delayed::Job.get_and_lock_next_available("test")
469
587
  run_job(job)
470
588
  # shouldn't error, and the job should now be deleted
471
- Delayed::Job.jobs_count(:current).should == 0
589
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
472
590
  end
473
591
 
474
- it "should allow overriding schedules using periodic_jobs.yml" do
475
- change_setting(Delayed::Periodic, :overrides, { 'my ChangedJob' => '*/10 * * * * *' }) do
592
+ it "allows overriding schedules using periodic_jobs.yml" do
593
+ change_setting(Delayed::Periodic, :overrides, { "my ChangedJob" => "*/10 * * * * *" }) do
476
594
  Delayed::Periodic.scheduled = {}
477
- Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
595
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
478
596
  Delayed::Job.enqueue(SimpleJob.new)
479
597
  end
480
- Delayed::Periodic.scheduled['my ChangedJob'].cron.original.should == '*/10 * * * * *'
598
+ expect(Delayed::Periodic.scheduled["my ChangedJob"].cron.original).to eq("*/10 * * * * *")
481
599
  end
482
600
  end
483
601
 
484
- it "should fail if the override cron line is invalid" do
485
- change_setting(Delayed::Periodic, :overrides, { 'my ChangedJob' => '*/10 * * * * * *' }) do # extra asterisk
602
+ it "fails if the override cron line is invalid" do
603
+ change_setting(Delayed::Periodic, :overrides, { "my ChangedJob" => "*/10 * * * * * *" }) do # extra asterisk
486
604
  Delayed::Periodic.scheduled = {}
487
- expect { Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
488
- Delayed::Job.enqueue(SimpleJob.new)
489
- end }.to raise_error(ArgumentError)
605
+ expect do
606
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
607
+ Delayed::Job.enqueue(SimpleJob.new)
608
+ end
609
+ end.to raise_error(ArgumentError)
490
610
  end
491
611
 
492
- expect { Delayed::Periodic.add_overrides({ 'my ChangedJob' => '*/10 * * * * * *' }) }.to raise_error(ArgumentError)
612
+ expect do
613
+ Delayed::Periodic.add_overrides({ "my ChangedJob" => "*/10 * * * * * *" })
614
+ end.to raise_error(ArgumentError)
493
615
  end
494
616
  end
495
617
 
496
- module InDelayedJobTest
497
- def self.check_in_job
498
- Delayed::Job.in_delayed_job?.should == true
499
- end
500
- end
501
-
502
- it "should set in_delayed_job?" do
618
+ it "sets in_delayed_job?" do
503
619
  job = InDelayedJobTest.delay(ignore_transaction: true).check_in_job
504
- Delayed::Job.in_delayed_job?.should == false
620
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
505
621
  job.invoke_job
506
- Delayed::Job.in_delayed_job?.should == false
622
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
507
623
  end
508
624
 
509
- it "should fail on job creation if an unsaved AR object is used" do
510
- story = Story.new :text => "Once upon..."
511
- lambda { story.delay.text }.should raise_error(RuntimeError)
625
+ it "fails on job creation if an unsaved AR object is used" do
626
+ story = Story.new text: "Once upon..."
627
+ expect { story.delay.text }.to raise_error(RuntimeError)
512
628
 
513
629
  reader = StoryReader.new
514
- lambda { reader.delay.read(story) }.should raise_error(RuntimeError)
630
+ expect { reader.delay.read(story) }.to raise_error(RuntimeError)
515
631
 
516
- lambda { [story, 1, story, false].delay.first }.should raise_error(RuntimeError)
632
+ expect { [story, 1, story, false].delay.first }.to raise_error(RuntimeError)
517
633
  end
518
634
 
519
635
  # the sort order of current_jobs and list_jobs depends on the back-end
@@ -521,62 +637,62 @@ shared_examples_for 'a backend' do
521
637
  describe "current jobs, queue size, strand_size" do
522
638
  before do
523
639
  @jobs = []
524
- 3.times { @jobs << create_job(:priority => 3) }
525
- @jobs.unshift create_job(:priority => 2)
526
- @jobs.unshift create_job(:priority => 1)
527
- @jobs << create_job(:priority => 3, :strand => "test1")
528
- @future_job = create_job(:run_at => 5.hours.from_now)
529
- 2.times { @jobs << create_job(:priority => 3) }
530
- @jobs << create_job(:priority => 3, :strand => "test1")
531
- @failed_job = create_job.tap { |j| j.fail! }
532
- @other_queue_job = create_job(:queue => "another")
640
+ 3.times { @jobs << create_job(priority: 3) }
641
+ @jobs.unshift create_job(priority: 2)
642
+ @jobs.unshift create_job(priority: 1)
643
+ @jobs << create_job(priority: 3, strand: "test1")
644
+ @future_job = create_job(run_at: 5.hours.from_now)
645
+ 2.times { @jobs << create_job(priority: 3) }
646
+ @jobs << create_job(priority: 3, strand: "test1")
647
+ @failed_job = create_job.tap(&:fail!)
648
+ @other_queue_job = create_job(queue: "another")
533
649
  end
534
650
 
535
- it "should return the queued jobs" do
536
- Delayed::Job.list_jobs(:current, 100).map(&:id).sort.should == @jobs.map(&:id).sort
651
+ it "returns the queued jobs" do
652
+ expect(Delayed::Job.list_jobs(:current, 100).map(&:id).sort).to eq(@jobs.map(&:id).sort)
537
653
  end
538
654
 
539
- it "should paginate the returned jobs" do
655
+ it "paginates the returned jobs" do
540
656
  @returned = []
541
657
  @returned += Delayed::Job.list_jobs(:current, 3, 0)
542
658
  @returned += Delayed::Job.list_jobs(:current, 4, 3)
543
659
  @returned += Delayed::Job.list_jobs(:current, 100, 7)
544
- @returned.sort_by { |j| j.id }.should == @jobs.sort_by { |j| j.id }
660
+ expect(@returned.sort_by(&:id)).to eq(@jobs.sort_by(&:id))
545
661
  end
546
662
 
547
- it "should return other queues" do
548
- Delayed::Job.list_jobs(:current, 5, 0, "another").should == [@other_queue_job]
663
+ it "returns other queues" do
664
+ expect(Delayed::Job.list_jobs(:current, 5, 0, "another")).to eq([@other_queue_job])
549
665
  end
550
666
 
551
- it "should return queue size" do
552
- Delayed::Job.jobs_count(:current).should == @jobs.size
553
- Delayed::Job.jobs_count(:current, "another").should == 1
554
- Delayed::Job.jobs_count(:current, "bogus").should == 0
667
+ it "returns queue size" do
668
+ expect(Delayed::Job.jobs_count(:current)).to eq(@jobs.size)
669
+ expect(Delayed::Job.jobs_count(:current, "another")).to eq(1)
670
+ expect(Delayed::Job.jobs_count(:current, "bogus")).to eq(0)
555
671
  end
556
672
 
557
- it "should return strand size" do
558
- Delayed::Job.strand_size("test1").should == 2
559
- Delayed::Job.strand_size("bogus").should == 0
673
+ it "returns strand size" do
674
+ expect(Delayed::Job.strand_size("test1")).to eq(2)
675
+ expect(Delayed::Job.strand_size("bogus")).to eq(0)
560
676
  end
561
677
  end
562
678
 
563
- it "should return the jobs in a strand" do
679
+ it "returns the jobs in a strand" do
564
680
  strand_jobs = []
565
- 3.times { strand_jobs << create_job(:strand => 'test1') }
566
- 2.times { create_job(:strand => 'test2') }
567
- strand_jobs << create_job(:strand => 'test1', :run_at => 5.hours.from_now)
681
+ 3.times { strand_jobs << create_job(strand: "test1") }
682
+ 2.times { create_job(strand: "test2") }
683
+ strand_jobs << create_job(strand: "test1", run_at: 5.hours.from_now)
568
684
  create_job
569
685
 
570
686
  jobs = Delayed::Job.list_jobs(:strand, 3, 0, "test1")
571
- jobs.size.should == 3
687
+ expect(jobs.size).to eq(3)
572
688
 
573
689
  jobs += Delayed::Job.list_jobs(:strand, 3, 3, "test1")
574
- jobs.size.should == 4
690
+ expect(jobs.size).to eq(4)
575
691
 
576
- jobs.sort_by { |j| j.id }.should == strand_jobs.sort_by { |j| j.id }
692
+ expect(jobs.sort_by(&:id)).to eq(strand_jobs.sort_by(&:id))
577
693
  end
578
694
 
579
- it "should return the jobs for a tag" do
695
+ it "returns the jobs for a tag" do
580
696
  tag_jobs = []
581
697
  3.times { tag_jobs << "test".delay(ignore_transaction: true).to_s }
582
698
  2.times { "test".delay.to_i }
@@ -586,62 +702,62 @@ shared_examples_for 'a backend' do
586
702
  create_job
587
703
 
588
704
  jobs = Delayed::Job.list_jobs(:tag, 3, 0, "String#to_s")
589
- jobs.size.should == 3
705
+ expect(jobs.size).to eq(3)
590
706
 
591
707
  jobs += Delayed::Job.list_jobs(:tag, 3, 3, "String#to_s")
592
- jobs.size.should == 5
708
+ expect(jobs.size).to eq(5)
593
709
 
594
- jobs.sort_by { |j| j.id }.should == tag_jobs.sort_by { |j| j.id }
710
+ expect(jobs.sort_by(&:id)).to eq(tag_jobs.sort_by(&:id))
595
711
  end
596
712
 
597
713
  describe "running_jobs" do
598
- it "should return the running jobs, ordered by locked_at" do
714
+ it "returns the running jobs, ordered by locked_at" do
599
715
  Timecop.freeze(10.minutes.ago) { 3.times { create_job } }
600
- j1 = Timecop.freeze(2.minutes.ago) { Delayed::Job.get_and_lock_next_available('w1') }
601
- j2 = Timecop.freeze(5.minutes.ago) { Delayed::Job.get_and_lock_next_available('w2') }
602
- j3 = Timecop.freeze(5.seconds.ago) { Delayed::Job.get_and_lock_next_available('w3') }
603
- [j1, j2, j3].compact.size.should == 3
716
+ j1 = Timecop.freeze(2.minutes.ago) { Delayed::Job.get_and_lock_next_available("w1") }
717
+ j2 = Timecop.freeze(5.minutes.ago) { Delayed::Job.get_and_lock_next_available("w2") }
718
+ j3 = Timecop.freeze(5.seconds.ago) { Delayed::Job.get_and_lock_next_available("w3") }
719
+ expect([j1, j2, j3].compact.size).to eq(3)
604
720
 
605
- Delayed::Job.running_jobs.should == [j2, j1, j3]
721
+ expect(Delayed::Job.running_jobs).to eq([j2, j1, j3])
606
722
  end
607
723
  end
608
724
 
609
725
  describe "future jobs" do
610
- it "should find future jobs once their run_at rolls by" do
611
- Timecop.freeze {
612
- @job = create_job :run_at => 5.minutes.from_now
726
+ it "finds future jobs once their run_at rolls by" do
727
+ Timecop.freeze do
728
+ @job = create_job run_at: 5.minutes.from_now
613
729
  expect(Delayed::Job.find_available(5)).not_to include(@job)
614
- }
615
- Timecop.freeze(1.hour.from_now) {
730
+ end
731
+ Timecop.freeze(1.hour.from_now) do
616
732
  expect(Delayed::Job.find_available(5)).to include(@job)
617
- Delayed::Job.get_and_lock_next_available('test').should == @job
618
- }
733
+ expect(Delayed::Job.get_and_lock_next_available("test")).to eq(@job)
734
+ end
619
735
  end
620
736
 
621
- it "should return future jobs sorted by their run_at" do
737
+ it "returns future jobs sorted by their run_at" do
622
738
  @j1 = create_job
623
- @j2 = create_job :run_at => 1.hour.from_now
624
- @j3 = create_job :run_at => 30.minutes.from_now
625
- Delayed::Job.list_jobs(:future, 1).should == [@j3]
626
- Delayed::Job.list_jobs(:future, 5).should == [@j3, @j2]
627
- Delayed::Job.list_jobs(:future, 1, 1).should == [@j2]
739
+ @j2 = create_job run_at: 1.hour.from_now
740
+ @j3 = create_job run_at: 30.minutes.from_now
741
+ expect(Delayed::Job.list_jobs(:future, 1)).to eq([@j3])
742
+ expect(Delayed::Job.list_jobs(:future, 5)).to eq([@j3, @j2])
743
+ expect(Delayed::Job.list_jobs(:future, 1, 1)).to eq([@j2])
628
744
  end
629
745
  end
630
746
 
631
747
  describe "failed jobs" do
632
748
  # the sort order of failed_jobs depends on the back-end implementation,
633
749
  # so sort order isn't tested here
634
- it "should return the list of failed jobs" do
750
+ it "returns the list of failed jobs" do
635
751
  jobs = []
636
- 3.times { jobs << create_job(:priority => 3) }
637
- jobs = jobs.sort_by { |j| j.id }
638
- Delayed::Job.list_jobs(:failed, 1).should == []
752
+ 3.times { jobs << create_job(priority: 3) }
753
+ jobs = jobs.sort_by(&:id)
754
+ expect(Delayed::Job.list_jobs(:failed, 1)).to eq([])
639
755
  jobs[0].fail!
640
756
  jobs[1].fail!
641
- failed = (Delayed::Job.list_jobs(:failed, 1, 0) + Delayed::Job.list_jobs(:failed, 1, 1)).sort_by { |j| j.id }
642
- failed.size.should == 2
643
- failed[0].original_job_id.should == jobs[0].id
644
- failed[1].original_job_id.should == jobs[1].id
757
+ failed = (Delayed::Job.list_jobs(:failed, 1, 0) + Delayed::Job.list_jobs(:failed, 1, 1)).sort_by(&:id)
758
+ expect(failed.size).to eq(2)
759
+ expect(failed[0].original_job_id).to eq(jobs[0].id)
760
+ expect(failed[1].original_job_id).to eq(jobs[1].id)
645
761
  end
646
762
  end
647
763
 
@@ -652,126 +768,123 @@ shared_examples_for 'a backend' do
652
768
  @ignored_jobs = []
653
769
  end
654
770
 
655
- it "should hold and unhold a scope of jobs" do
656
- @affected_jobs.all? { |j| j.on_hold? }.should be false
657
- @ignored_jobs.any? { |j| j.on_hold? }.should be false
658
- Delayed::Job.bulk_update('hold', :flavor => @flavor, :query => @query).should == @affected_jobs.size
771
+ it "holds and unhold a scope of jobs" do
772
+ expect(@affected_jobs.all?(&:on_hold?)).to be false
773
+ expect(@ignored_jobs.any?(&:on_hold?)).to be false
774
+ expect(Delayed::Job.bulk_update("hold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
659
775
 
660
- @affected_jobs.all? { |j| Delayed::Job.find(j.id).on_hold? }.should be true
661
- @ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
776
+ expect(@affected_jobs.all? { |j| Delayed::Job.find(j.id).on_hold? }).to be true
777
+ expect(@ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
662
778
 
663
- # redis holding seems busted - it removes from the tag set and strand list, so you can't use a query
664
- # to un-hold them
665
- next if Delayed::Job == Delayed::Backend::Redis::Job
666
- Delayed::Job.bulk_update('unhold', :flavor => @flavor, :query => @query).should == @affected_jobs.size
779
+ expect(Delayed::Job.bulk_update("unhold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
667
780
 
668
- @affected_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
669
- @ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
781
+ expect(@affected_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
782
+ expect(@ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
670
783
  end
671
784
 
672
- it "should delete a scope of jobs" do
673
- Delayed::Job.bulk_update('destroy', :flavor => @flavor, :query => @query).should == @affected_jobs.size
674
- @affected_jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.should be_blank
675
- @ignored_jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.size.should == @ignored_jobs.size
785
+ it "deletes a scope of jobs" do
786
+ expect(Delayed::Job.bulk_update("destroy", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
787
+ expect(Delayed::Job.where(id: @affected_jobs.map(&:id))).not_to exist
788
+ expect(Delayed::Job.where(id: @ignored_jobs.map(&:id)).count).to eq @ignored_jobs.size
676
789
  end
677
790
  end
678
791
 
679
792
  describe "scope: current" do
680
793
  include_examples "scope"
681
- before do
682
- @flavor = 'current'
794
+ before do # rubocop:disable RSpec/HooksBeforeExamples
795
+ @flavor = "current"
683
796
  Timecop.freeze(5.minutes.ago) do
684
797
  3.times { @affected_jobs << create_job }
685
- @ignored_jobs << create_job(:run_at => 2.hours.from_now)
686
- @ignored_jobs << create_job(:queue => 'q2')
798
+ @ignored_jobs << create_job(run_at: 2.hours.from_now)
799
+ @ignored_jobs << create_job(queue: "q2")
687
800
  end
688
801
  end
689
802
  end
690
803
 
691
804
  describe "scope: future" do
692
805
  include_examples "scope"
693
- before do
694
- @flavor = 'future'
806
+ before do # rubocop:disable RSpec/HooksBeforeExamples
807
+ @flavor = "future"
695
808
  Timecop.freeze(5.minutes.ago) do
696
- 3.times { @affected_jobs << create_job(:run_at => 2.hours.from_now) }
809
+ 3.times { @affected_jobs << create_job(run_at: 2.hours.from_now) }
697
810
  @ignored_jobs << create_job
698
- @ignored_jobs << create_job(:queue => 'q2', :run_at => 2.hours.from_now)
811
+ @ignored_jobs << create_job(queue: "q2", run_at: 2.hours.from_now)
699
812
  end
700
813
  end
701
814
  end
702
815
 
703
816
  describe "scope: strand" do
704
817
  include_examples "scope"
705
- before do
706
- @flavor = 'strand'
707
- @query = 's1'
818
+ before do # rubocop:disable RSpec/HooksBeforeExamples
819
+ @flavor = "strand"
820
+ @query = "s1"
708
821
  Timecop.freeze(5.minutes.ago) do
709
- @affected_jobs << create_job(:strand => 's1')
710
- @affected_jobs << create_job(:strand => 's1', :run_at => 2.hours.from_now)
822
+ @affected_jobs << create_job(strand: "s1")
823
+ @affected_jobs << create_job(strand: "s1", run_at: 2.hours.from_now)
711
824
  @ignored_jobs << create_job
712
- @ignored_jobs << create_job(:strand => 's2')
713
- @ignored_jobs << create_job(:strand => 's2', :run_at => 2.hours.from_now)
825
+ @ignored_jobs << create_job(strand: "s2")
826
+ @ignored_jobs << create_job(strand: "s2", run_at: 2.hours.from_now)
714
827
  end
715
828
  end
716
829
  end
717
830
 
718
831
  describe "scope: tag" do
719
832
  include_examples "scope"
720
- before do
721
- @flavor = 'tag'
722
- @query = 'String#to_i'
833
+ before do # rubocop:disable RSpec/HooksBeforeExamples
834
+ @flavor = "tag"
835
+ @query = "String#to_i"
723
836
  Timecop.freeze(5.minutes.ago) do
724
837
  @affected_jobs << "test".delay(ignore_transaction: true).to_i
725
- @affected_jobs << "test".delay(strand: 's1', ignore_transaction: true).to_i
838
+ @affected_jobs << "test".delay(strand: "s1", ignore_transaction: true).to_i
726
839
  @affected_jobs << "test".delay(run_at: 2.hours.from_now, ignore_transaction: true).to_i
727
840
  @ignored_jobs << create_job
728
- @ignored_jobs << create_job(:run_at => 1.hour.from_now)
841
+ @ignored_jobs << create_job(run_at: 1.hour.from_now)
729
842
  end
730
843
  end
731
844
  end
732
845
 
733
- it "should hold and un-hold given job ids" do
846
+ it "holds and un-hold given job ids" do
734
847
  j1 = "test".delay(ignore_transaction: true).to_i
735
- j2 = create_job(:run_at => 2.hours.from_now)
736
- j3 = "test".delay(strand: 's1', ignore_transaction: true).to_i
737
- Delayed::Job.bulk_update('hold', :ids => [j1.id, j2.id]).should == 2
738
- Delayed::Job.find(j1.id).on_hold?.should be true
739
- Delayed::Job.find(j2.id).on_hold?.should be true
740
- Delayed::Job.find(j3.id).on_hold?.should be false
848
+ j2 = create_job(run_at: 2.hours.from_now)
849
+ j3 = "test".delay(strand: "s1", ignore_transaction: true).to_i
850
+ expect(Delayed::Job.bulk_update("hold", ids: [j1.id, j2.id])).to eq(2)
851
+ expect(Delayed::Job.find(j1.id).on_hold?).to be true
852
+ expect(Delayed::Job.find(j2.id).on_hold?).to be true
853
+ expect(Delayed::Job.find(j3.id).on_hold?).to be false
741
854
 
742
- Delayed::Job.bulk_update('unhold', :ids => [j2.id, j3.id]).should == 1
743
- Delayed::Job.find(j1.id).on_hold?.should be true
744
- Delayed::Job.find(j2.id).on_hold?.should be false
745
- Delayed::Job.find(j3.id).on_hold?.should be false
855
+ expect(Delayed::Job.bulk_update("unhold", ids: [j2.id, j3.id])).to eq(1)
856
+ expect(Delayed::Job.find(j1.id).on_hold?).to be true
857
+ expect(Delayed::Job.find(j2.id).on_hold?).to be false
858
+ expect(Delayed::Job.find(j3.id).on_hold?).to be false
746
859
  end
747
860
 
748
- it "should not hold locked jobs" do
749
- job1 = Delayed::Job.new(:tag => 'tag')
861
+ it "does not hold locked jobs" do
862
+ job1 = Delayed::Job.new(tag: "tag")
750
863
  job1.create_and_lock!("worker")
751
- job1.on_hold?.should be false
752
- Delayed::Job.bulk_update('hold', ids: [job1.id]).should == 0
753
- Delayed::Job.find(job1.id).on_hold?.should be false
864
+ expect(job1.on_hold?).to be false
865
+ expect(Delayed::Job.bulk_update("hold", ids: [job1.id])).to eq(0)
866
+ expect(Delayed::Job.find(job1.id).on_hold?).to be false
754
867
  end
755
868
 
756
- it "should not unhold locked jobs" do
757
- job1 = Delayed::Job.new(:tag => 'tag')
869
+ it "does not unhold locked jobs" do
870
+ job1 = Delayed::Job.new(tag: "tag")
758
871
  job1.create_and_lock!("worker")
759
- Delayed::Job.bulk_update('unhold', ids: [job1.id]).should == 0
760
- Delayed::Job.find(job1.id).on_hold?.should be false
761
- Delayed::Job.find(job1.id).locked?.should be true
872
+ expect(Delayed::Job.bulk_update("unhold", ids: [job1.id])).to eq(0)
873
+ expect(Delayed::Job.find(job1.id).on_hold?).to be false
874
+ expect(Delayed::Job.find(job1.id).locked?).to be true
762
875
  end
763
876
 
764
- it "should delete given job ids" do
877
+ it "deletes given job ids" do
765
878
  jobs = (0..2).map { create_job }
766
- Delayed::Job.bulk_update('destroy', :ids => jobs[0,2].map(&:id)).should == 2
767
- jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.should == jobs[2,1]
879
+ expect(Delayed::Job.bulk_update("destroy", ids: jobs[0, 2].map(&:id))).to eq(2)
880
+ expect(Delayed::Job.order(:id).where(id: jobs.map(&:id))).to eq jobs[2, 1]
768
881
  end
769
882
 
770
- it "should not delete locked jobs" do
771
- job1 = Delayed::Job.new(:tag => 'tag')
883
+ it "does not delete locked jobs" do
884
+ job1 = Delayed::Job.new(tag: "tag")
772
885
  job1.create_and_lock!("worker")
773
- Delayed::Job.bulk_update('destroy', ids: [job1.id]).should == 0
774
- Delayed::Job.find(job1.id).locked?.should be true
886
+ expect(Delayed::Job.bulk_update("destroy", ids: [job1.id])).to eq(0)
887
+ expect(Delayed::Job.find(job1.id).locked?).to be true
775
888
  end
776
889
  end
777
890
 
@@ -779,7 +892,7 @@ shared_examples_for 'a backend' do
779
892
  before do
780
893
  @cur = []
781
894
  3.times { @cur << "test".delay(ignore_transaction: true).to_s }
782
- 5.times { @cur << "test".delay(ignore_transaction: true).to_i}
895
+ 5.times { @cur << "test".delay(ignore_transaction: true).to_i }
783
896
  2.times { @cur << "test".delay(ignore_transaction: true).upcase }
784
897
  "test".delay(ignore_transaction: true).downcase.fail!
785
898
  @future = []
@@ -787,48 +900,48 @@ shared_examples_for 'a backend' do
787
900
  @cur << "test".delay(ignore_transaction: true).downcase
788
901
  end
789
902
 
790
- it "should return a sorted list of popular current tags" do
791
- Delayed::Job.tag_counts(:current, 1).should == [{ :tag => "String#to_i", :count => 5 }]
792
- Delayed::Job.tag_counts(:current, 1, 1).should == [{ :tag => "String#to_s", :count => 3 }]
793
- Delayed::Job.tag_counts(:current, 5).should == [{ :tag => "String#to_i", :count => 5 },
794
- { :tag => "String#to_s", :count => 3 },
795
- { :tag => "String#upcase", :count => 2 },
796
- { :tag => "String#downcase", :count => 1 }]
797
- @cur[0,4].each { |j| j.destroy }
903
+ it "returns a sorted list of popular current tags" do
904
+ expect(Delayed::Job.tag_counts(:current, 1)).to eq([{ tag: "String#to_i", count: 5 }])
905
+ expect(Delayed::Job.tag_counts(:current, 1, 1)).to eq([{ tag: "String#to_s", count: 3 }])
906
+ expect(Delayed::Job.tag_counts(:current, 5)).to eq([{ tag: "String#to_i", count: 5 },
907
+ { tag: "String#to_s", count: 3 },
908
+ { tag: "String#upcase", count: 2 },
909
+ { tag: "String#downcase", count: 1 }])
910
+ @cur[0, 4].each(&:destroy)
798
911
  @future[0].run_at = @future[1].run_at = 1.hour.ago
799
912
  @future[0].save!
800
913
  @future[1].save!
801
914
 
802
- Delayed::Job.tag_counts(:current, 5).should == [{ :tag => "String#to_i", :count => 4 },
803
- { :tag => "String#downcase", :count => 3 },
804
- { :tag => "String#upcase", :count => 2 },]
915
+ expect(Delayed::Job.tag_counts(:current, 5)).to eq([{ tag: "String#to_i", count: 4 },
916
+ { tag: "String#downcase", count: 3 },
917
+ { tag: "String#upcase", count: 2 }])
805
918
  end
806
919
 
807
- it "should return a sorted list of all popular tags" do
808
- Delayed::Job.tag_counts(:all, 1).should == [{ :tag => "String#downcase", :count => 6 }]
809
- Delayed::Job.tag_counts(:all, 1, 1).should == [{ :tag => "String#to_i", :count => 5 }]
810
- Delayed::Job.tag_counts(:all, 5).should == [{ :tag => "String#downcase", :count => 6 },
811
- { :tag => "String#to_i", :count => 5 },
812
- { :tag => "String#to_s", :count => 3 },
813
- { :tag => "String#upcase", :count => 2 },]
920
+ it "returns a sorted list of all popular tags" do
921
+ expect(Delayed::Job.tag_counts(:all, 1)).to eq([{ tag: "String#downcase", count: 6 }])
922
+ expect(Delayed::Job.tag_counts(:all, 1, 1)).to eq([{ tag: "String#to_i", count: 5 }])
923
+ expect(Delayed::Job.tag_counts(:all, 5)).to eq([{ tag: "String#downcase", count: 6 },
924
+ { tag: "String#to_i", count: 5 },
925
+ { tag: "String#to_s", count: 3 },
926
+ { tag: "String#upcase", count: 2 }])
814
927
 
815
- @cur[0,4].each { |j| j.destroy }
928
+ @cur[0, 4].each(&:destroy)
816
929
  @future[0].destroy
817
930
  @future[1].fail!
818
931
  @future[2].fail!
819
932
 
820
- Delayed::Job.tag_counts(:all, 5).should == [{ :tag => "String#to_i", :count => 4 },
821
- { :tag => "String#downcase", :count => 3 },
822
- { :tag => "String#upcase", :count => 2 },]
933
+ expect(Delayed::Job.tag_counts(:all, 5)).to eq([{ tag: "String#to_i", count: 4 },
934
+ { tag: "String#downcase", count: 3 },
935
+ { tag: "String#upcase", count: 2 }])
823
936
  end
824
937
  end
825
938
 
826
- it "should unlock orphaned jobs" do
939
+ it "unlocks orphaned jobs" do
827
940
  change_setting(Delayed::Settings, :max_attempts, 2) do
828
- job1 = Delayed::Job.new(:tag => 'tag')
829
- job2 = Delayed::Job.new(:tag => 'tag')
830
- job3 = Delayed::Job.new(:tag => 'tag')
831
- job4 = Delayed::Job.new(:tag => 'tag')
941
+ job1 = Delayed::Job.new(tag: "tag")
942
+ job2 = Delayed::Job.new(tag: "tag")
943
+ job3 = Delayed::Job.new(tag: "tag")
944
+ job4 = Delayed::Job.new(tag: "tag")
832
945
  job1.create_and_lock!("Jobworker:#{Process.pid}")
833
946
  `echo ''`
834
947
  child_pid = $?.pid
@@ -836,23 +949,23 @@ shared_examples_for 'a backend' do
836
949
  job3.create_and_lock!("someoneelse:#{Process.pid}")
837
950
  job4.create_and_lock!("Jobworker:notanumber")
838
951
 
839
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 1
952
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(1)
840
953
 
841
- Delayed::Job.find(job1.id).locked_by.should_not be_nil
842
- Delayed::Job.find(job2.id).locked_by.should be_nil
843
- Delayed::Job.find(job3.id).locked_by.should_not be_nil
844
- Delayed::Job.find(job4.id).locked_by.should_not be_nil
954
+ expect(Delayed::Job.find(job1.id).locked_by).not_to be_nil
955
+ expect(Delayed::Job.find(job2.id).locked_by).to be_nil
956
+ expect(Delayed::Job.find(job3.id).locked_by).not_to be_nil
957
+ expect(Delayed::Job.find(job4.id).locked_by).not_to be_nil
845
958
 
846
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 0
959
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(0)
847
960
  end
848
961
  end
849
962
 
850
- it "should unlock orphaned jobs given a pid" do
963
+ it "unlocks orphaned jobs given a pid" do
851
964
  change_setting(Delayed::Settings, :max_attempts, 2) do
852
- job1 = Delayed::Job.new(:tag => 'tag')
853
- job2 = Delayed::Job.new(:tag => 'tag')
854
- job3 = Delayed::Job.new(:tag => 'tag')
855
- job4 = Delayed::Job.new(:tag => 'tag')
965
+ job1 = Delayed::Job.new(tag: "tag")
966
+ job2 = Delayed::Job.new(tag: "tag")
967
+ job3 = Delayed::Job.new(tag: "tag")
968
+ job4 = Delayed::Job.new(tag: "tag")
856
969
  job1.create_and_lock!("Jobworker:#{Process.pid}")
857
970
  `echo ''`
858
971
  child_pid = $?.pid
@@ -862,15 +975,15 @@ shared_examples_for 'a backend' do
862
975
  job3.create_and_lock!("someoneelse:#{Process.pid}")
863
976
  job4.create_and_lock!("Jobworker:notanumber")
864
977
 
865
- Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker").should == 0
866
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 1
978
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker")).to eq(0)
979
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(1)
867
980
 
868
- Delayed::Job.find(job1.id).locked_by.should_not be_nil
869
- Delayed::Job.find(job2.id).locked_by.should be_nil
870
- Delayed::Job.find(job3.id).locked_by.should_not be_nil
871
- Delayed::Job.find(job4.id).locked_by.should_not be_nil
981
+ expect(Delayed::Job.find(job1.id).locked_by).not_to be_nil
982
+ expect(Delayed::Job.find(job2.id).locked_by).to be_nil
983
+ expect(Delayed::Job.find(job3.id).locked_by).not_to be_nil
984
+ expect(Delayed::Job.find(job4.id).locked_by).not_to be_nil
872
985
 
873
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 0
986
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(0)
874
987
  end
875
988
  end
876
989
  end