inst-jobs 2.0.0 → 3.0.0

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.
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