inst-jobs 2.3.3 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) 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 +3 -3
  21. data/db/migrate/20210812210128_add_singleton_column.rb +203 -0
  22. data/exe/inst_jobs +3 -2
  23. data/lib/delayed/backend/active_record.rb +182 -148
  24. data/lib/delayed/backend/base.rb +79 -74
  25. data/lib/delayed/batch.rb +11 -9
  26. data/lib/delayed/cli.rb +98 -84
  27. data/lib/delayed/core_ext/kernel.rb +4 -2
  28. data/lib/delayed/daemon.rb +70 -74
  29. data/lib/delayed/job_tracking.rb +26 -25
  30. data/lib/delayed/lifecycle.rb +27 -24
  31. data/lib/delayed/log_tailer.rb +17 -17
  32. data/lib/delayed/logging.rb +13 -16
  33. data/lib/delayed/message_sending.rb +42 -51
  34. data/lib/delayed/performable_method.rb +5 -7
  35. data/lib/delayed/periodic.rb +66 -65
  36. data/lib/delayed/plugin.rb +2 -4
  37. data/lib/delayed/pool.rb +198 -193
  38. data/lib/delayed/server/helpers.rb +6 -6
  39. data/lib/delayed/server.rb +51 -54
  40. data/lib/delayed/settings.rb +93 -81
  41. data/lib/delayed/testing.rb +21 -22
  42. data/lib/delayed/version.rb +1 -1
  43. data/lib/delayed/work_queue/in_process.rb +21 -18
  44. data/lib/delayed/work_queue/parent_process/client.rb +54 -55
  45. data/lib/delayed/work_queue/parent_process/server.rb +215 -209
  46. data/lib/delayed/work_queue/parent_process.rb +52 -53
  47. data/lib/delayed/worker/consul_health_check.rb +21 -19
  48. data/lib/delayed/worker/health_check.rb +21 -12
  49. data/lib/delayed/worker/null_health_check.rb +3 -1
  50. data/lib/delayed/worker/process_helper.rb +8 -9
  51. data/lib/delayed/worker.rb +271 -265
  52. data/lib/delayed/yaml_extensions.rb +12 -10
  53. data/lib/delayed_job.rb +37 -38
  54. data/lib/inst-jobs.rb +1 -1
  55. data/spec/active_record_job_spec.rb +128 -135
  56. data/spec/delayed/cli_spec.rb +7 -7
  57. data/spec/delayed/daemon_spec.rb +8 -8
  58. data/spec/delayed/message_sending_spec.rb +8 -9
  59. data/spec/delayed/periodic_spec.rb +13 -12
  60. data/spec/delayed/server_spec.rb +38 -38
  61. data/spec/delayed/settings_spec.rb +26 -25
  62. data/spec/delayed/work_queue/in_process_spec.rb +7 -7
  63. data/spec/delayed/work_queue/parent_process/client_spec.rb +15 -11
  64. data/spec/delayed/work_queue/parent_process/server_spec.rb +43 -40
  65. data/spec/delayed/work_queue/parent_process_spec.rb +21 -21
  66. data/spec/delayed/worker/consul_health_check_spec.rb +22 -22
  67. data/spec/delayed/worker/health_check_spec.rb +51 -49
  68. data/spec/delayed/worker_spec.rb +28 -25
  69. data/spec/gemfiles/52.gemfile +5 -3
  70. data/spec/gemfiles/52.gemfile.lock +240 -0
  71. data/spec/gemfiles/60.gemfile +5 -3
  72. data/spec/gemfiles/60.gemfile.lock +1 -1
  73. data/spec/gemfiles/61.gemfile +5 -3
  74. data/spec/sample_jobs.rb +45 -15
  75. data/spec/shared/delayed_batch.rb +74 -67
  76. data/spec/shared/delayed_method.rb +143 -102
  77. data/spec/shared/performable_method.rb +39 -38
  78. data/spec/shared/shared_backend.rb +517 -441
  79. data/spec/shared/testing.rb +14 -14
  80. data/spec/shared/worker.rb +155 -147
  81. data/spec/shared_jobs_specs.rb +13 -13
  82. data/spec/spec_helper.rb +43 -40
  83. metadata +74 -56
  84. data/lib/delayed/backend/redis/bulk_update.lua +0 -50
  85. data/lib/delayed/backend/redis/destroy_job.lua +0 -2
  86. data/lib/delayed/backend/redis/enqueue.lua +0 -29
  87. data/lib/delayed/backend/redis/fail_job.lua +0 -5
  88. data/lib/delayed/backend/redis/find_available.lua +0 -3
  89. data/lib/delayed/backend/redis/functions.rb +0 -59
  90. data/lib/delayed/backend/redis/get_and_lock_next_available.lua +0 -17
  91. data/lib/delayed/backend/redis/includes/jobs_common.lua +0 -203
  92. data/lib/delayed/backend/redis/job.rb +0 -528
  93. data/lib/delayed/backend/redis/set_running.lua +0 -5
  94. data/lib/delayed/backend/redis/tickle_strand.lua +0 -2
  95. data/spec/redis_job_spec.rb +0 -148
@@ -1,73 +1,74 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- shared_examples_for 'Delayed::PerformableMethod' do
4
-
5
- it "should not ignore ActiveRecord::RecordNotFound errors because they are not always permanent" do
6
- story = Story.create :text => 'Once upon...'
3
+ shared_examples_for "Delayed::PerformableMethod" do
4
+ it "does not ignore ActiveRecord::RecordNotFound errors because they are not always permanent" do
5
+ story = Story.create text: "Once upon..."
7
6
  p = Delayed::PerformableMethod.new(story, :tell)
8
7
  story.destroy
9
- lambda { YAML.load(p.to_yaml) }.should raise_error(Delayed::Backend::RecordNotFound)
8
+ expect { YAML.load(p.to_yaml) }.to raise_error(Delayed::Backend::RecordNotFound)
10
9
  end
11
10
 
12
- it "should store the object using native YAML even if its an active record" do
13
- story = Story.create :text => 'Once upon...'
11
+ it "stores the object using native YAML even if its an active record" do
12
+ story = Story.create text: "Once upon..."
14
13
  p = Delayed::PerformableMethod.new(story, :tell)
15
- p.class.should == Delayed::PerformableMethod
16
- p.object.should == story
17
- p.method.should == :tell
18
- p.args.should == []
19
- p.perform.should == 'Once upon...'
14
+ expect(p.class).to eq(Delayed::PerformableMethod)
15
+ expect(p.object).to eq(story)
16
+ expect(p.method).to eq(:tell)
17
+ expect(p.args).to eq([])
18
+ expect(p.perform).to eq("Once upon...")
20
19
  end
21
20
 
22
- it "should allow class methods to be called on ActiveRecord models" do
23
- Story.create!(:text => 'Once upon a...')
21
+ it "allows class methods to be called on ActiveRecord models" do
22
+ Story.create!(text: "Once upon a...")
24
23
  p = Delayed::PerformableMethod.new(Story, :count)
25
- lambda { expect(p.send(:perform)).to eql 1 }.should_not raise_error
24
+ expect { expect(p.send(:perform)).to be 1 }.not_to raise_error
26
25
  end
27
26
 
28
- it "should allow class methods to be called" do
27
+ it "allows class methods to be called" do
29
28
  p = Delayed::PerformableMethod.new(StoryReader, :reverse, args: ["ohai"])
30
- lambda { p.send(:perform).should == "iaho" }.should_not raise_error
29
+ expect { expect(p.send(:perform)).to eq("iaho") }.not_to raise_error
31
30
  end
32
31
 
33
- it "should allow module methods to be called" do
32
+ it "allows module methods to be called" do
34
33
  p = Delayed::PerformableMethod.new(MyReverser, :reverse, args: ["ohai"])
35
- lambda { p.send(:perform).should == "iaho" }.should_not raise_error
34
+ expect { expect(p.send(:perform)).to eq("iaho") }.not_to raise_error
36
35
  end
37
36
 
38
- it "should store arguments as native YAML if they are active record objects" do
39
- story = Story.create :text => 'Once upon...'
37
+ it "stores arguments as native YAML if they are active record objects" do
38
+ story = Story.create text: "Once upon..."
40
39
  reader = StoryReader.new
41
40
  p = Delayed::PerformableMethod.new(reader, :read, args: [story])
42
- p.class.should == Delayed::PerformableMethod
43
- p.method.should == :read
44
- p.args.should == [story]
45
- p.perform.should == 'Epilog: Once upon...'
41
+ expect(p.class).to eq(Delayed::PerformableMethod)
42
+ expect(p.method).to eq(:read)
43
+ expect(p.args).to eq([story])
44
+ expect(p.perform).to eq("Epilog: Once upon...")
46
45
  end
47
46
 
48
- it "should deeply de-AR-ize arguments in full name" do
49
- story = Story.create :text => 'Once upon...'
47
+ it "deeplies de-AR-ize arguments in full name" do
48
+ story = Story.create text: "Once upon..."
50
49
  reader = StoryReader.new
51
- p = Delayed::PerformableMethod.new(reader, :read, args: [['arg1', story, { [:key, 1] => story }]])
52
- p.full_name.should == "StoryReader#read([\"arg1\", Story.find(#{story.id}), {[:key, 1] => Story.find(#{story.id})}])"
50
+ p = Delayed::PerformableMethod.new(reader, :read, args: [["arg1", story, { [:key, 1] => story }]])
51
+ expect(p.full_name).to eq(
52
+ "StoryReader#read([\"arg1\", Story.find(#{story.id}), {[:key, 1] => Story.find(#{story.id})}])"
53
+ )
53
54
  end
54
55
 
55
- it "should call the on_failure callback" do
56
- story = Story.create :text => 'wat'
56
+ it "calls the on_failure callback" do
57
+ story = Story.create text: "wat"
57
58
  p = Delayed::PerformableMethod.new(story, :tell, on_failure: :text=)
58
- p.send(:on_failure, 'fail')
59
- story.text.should == 'fail'
59
+ p.send(:on_failure, "fail")
60
+ expect(story.text).to eq("fail")
60
61
  end
61
62
 
62
- it "should call the on_permanent_failure callback" do
63
- story = Story.create :text => 'wat'
63
+ it "calls the on_permanent_failure callback" do
64
+ story = Story.create text: "wat"
64
65
  p = Delayed::PerformableMethod.new(story, :tell, on_permanent_failure: :text=)
65
- p.send(:on_permanent_failure, 'fail_frd')
66
- story.text.should == 'fail_frd'
66
+ p.send(:on_permanent_failure, "fail_frd")
67
+ expect(story.text).to eq("fail_frd")
67
68
  end
68
69
 
69
70
  it "can still generate a name with no kwargs" do
70
- story = Story.create :text => 'wat'
71
+ story = Story.create text: "wat"
71
72
  p = Delayed::PerformableMethod.new(story, :tell, kwargs: nil)
72
73
  expect(p.full_name).to eq("Story.find(#{story.id}).tell()")
73
74
  end
@@ -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,302 +230,376 @@ 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
321
  it "complains if you pass more than one strand-based option" do
317
- expect { create_job(strand: 'a', n_strand: 'b') }.to raise_error(ArgumentError)
318
- expect { create_job(strand: 'a', singleton: 'b') }.to raise_error(ArgumentError)
319
- expect { create_job(n_strand: 'a', singleton: 'b') }.to raise_error(ArgumentError)
320
- expect { create_job(strand: 'a', n_strand: 'b', singleton: 'c') }.to raise_error(ArgumentError)
322
+ expect { create_job(strand: "a", n_strand: "b") }.to raise_error(ArgumentError)
321
323
  end
322
324
 
323
- context 'singleton' do
324
- it "should create if there's no jobs on the strand" do
325
- @job = create_job(:singleton => 'myjobs')
326
- @job.should be_present
327
- Delayed::Job.get_and_lock_next_available('w1').should == @job
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)
328
330
  end
329
331
 
330
- it "should create if there's another job on the strand, but it's running" do
331
- @job = create_job(:singleton => 'myjobs')
332
- @job.should be_present
333
- 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)
334
336
 
335
- @job2 = create_job(:singleton => 'myjobs')
336
- @job.should be_present
337
- @job2.should_not == @job
337
+ @job2 = create_job(singleton: "myjobs")
338
+ expect(@job).to be_present
339
+ expect(@job2).not_to eq(@job)
338
340
  end
339
341
 
340
- it "should not create if there's another non-running job on the strand" do
341
- @job = create_job(:singleton => 'myjobs')
342
- @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
343
345
 
344
- @job2 = create_job(:singleton => 'myjobs')
345
- @job2.should == @job
346
+ @job2 = create_job(singleton: "myjobs")
347
+ expect(@job2).to be_new_record
346
348
  end
347
349
 
348
- it "should not create if there's a job running and one waiting on the strand" do
349
- @job = create_job(:singleton => 'myjobs')
350
- @job.should be_present
351
- 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)
352
354
 
353
- @job2 = create_job(:singleton => 'myjobs')
354
- @job2.should be_present
355
- @job2.should_not == @job
355
+ @job2 = create_job(singleton: "myjobs")
356
+ expect(@job2).to be_present
357
+ expect(@job2).not_to eq(@job)
356
358
 
357
- @job3 = create_job(:singleton => 'myjobs')
358
- @job3.should == @job2
359
+ @job3 = create_job(singleton: "myjobs")
360
+ expect(@job3).to be_new_record
359
361
  end
360
362
 
361
- it "should update existing job if new job is set to run sooner" do
362
- job1 = create_job(singleton: 'myjobs', run_at: 1.hour.from_now)
363
- job2 = create_job(singleton: 'myjobs')
364
- 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)
365
367
  # it should be scheduled to run immediately
366
- Delayed::Job.get_and_lock_next_available('w1').should == job1
368
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
367
369
  end
368
370
 
369
- it "should update existing job to a later date if requested" do
371
+ it "updates existing job to a later date if requested" do
370
372
  t1 = 1.hour.from_now
371
373
  t2 = 2.hours.from_now
372
- job1 = create_job(singleton: 'myjobs', run_at: t1)
373
- job2 = create_job(singleton: 'myjobs', run_at: t2)
374
- job2.should == job1
375
- job2.run_at.to_i.should == t1.to_i
376
-
377
- job3 = create_job(singleton: 'myjobs', run_at: t2, on_conflict: :overwrite)
378
- job3.should == job1
379
- 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)
380
381
  end
381
382
 
382
- it "should update existing singleton job handler if requested" do
383
- job1 = Delayed::Job.enqueue(SimpleJob.new, queue: nil, singleton: 'myjobs', on_conflict: :overwrite)
384
- job2 = Delayed::Job.enqueue(ErrorJob.new, queue: nil, singleton: 'myjobs', on_conflict: :overwrite)
385
- job2.should == job1
386
- 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")
387
388
  end
388
389
 
389
- it "does not create even if it's earlier when in loose mode" do
390
- t1 = 1.hour.from_now
391
- job1 = create_job(singleton: 'myjobs', run_at: t1)
392
- job2 = create_job(singleton: 'myjobs', on_conflict: :loose)
393
- job1.should == job2
394
- 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
395
476
  end
396
477
  end
397
478
  end
398
479
 
399
480
  context "on hold" do
400
- it "should hold/unhold jobs" do
401
- job1 = create_job()
481
+ it "hold/unholds jobs" do
482
+ job1 = create_job
402
483
  job1.hold!
403
- Delayed::Job.get_and_lock_next_available('w1').should be_nil
484
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
404
485
 
405
486
  job1.unhold!
406
- Delayed::Job.get_and_lock_next_available('w1').should == job1
487
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
407
488
  end
408
489
  end
409
490
 
410
491
  context "periodic jobs" do
411
- before(:each) do
492
+ before do
412
493
  # make the periodic job get scheduled in the past
413
494
  @cron_time = 10.minutes.ago
414
495
  allow(Delayed::Periodic).to receive(:now).and_return(@cron_time)
415
496
  Delayed::Periodic.scheduled = {}
416
- Delayed::Periodic.cron('my SimpleJob', '*/5 * * * * *') do
497
+ Delayed::Periodic.cron("my SimpleJob", "*/5 * * * * *") do
417
498
  Delayed::Job.enqueue(SimpleJob.new)
418
499
  end
419
500
  end
420
501
 
421
- it "should schedule jobs if they aren't scheduled yet" do
422
- Delayed::Job.jobs_count(:current).should == 0
502
+ it "schedules jobs if they aren't scheduled yet" do
503
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
423
504
  Delayed::Periodic.perform_audit!
424
- Delayed::Job.jobs_count(:current).should == 1
425
- job = Delayed::Job.get_and_lock_next_available('test1')
426
- job.tag.should == 'periodic: my SimpleJob'
427
- job.payload_object.should == Delayed::Periodic.scheduled['my SimpleJob']
428
- job.run_at.should >= @cron_time
429
- job.run_at.should <= @cron_time + 6.minutes
430
- job.strand.should == job.tag
505
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
506
+ job = Delayed::Job.get_and_lock_next_available("test1")
507
+ expect(job.tag).to eq("periodic: my SimpleJob")
508
+ expect(job.payload_object).to eq(Delayed::Periodic.scheduled["my SimpleJob"])
509
+ expect(job.run_at).to be >= @cron_time
510
+ expect(job.run_at).to be <= @cron_time + 6.minutes
511
+ expect(job.singleton).to eq(job.tag)
431
512
  end
432
513
 
433
- it "should schedule jobs if there are only failed jobs on the queue" do
434
- Delayed::Job.jobs_count(:current).should == 0
514
+ it "schedules jobs if there are only failed jobs on the queue" do
515
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
435
516
  expect { Delayed::Periodic.perform_audit! }.to change { Delayed::Job.jobs_count(:current) }.by(1)
436
- Delayed::Job.jobs_count(:current).should == 1
437
- job = Delayed::Job.get_and_lock_next_available('test1')
517
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
518
+ job = Delayed::Job.get_and_lock_next_available("test1")
438
519
  job.fail!
439
- expect { Delayed::Periodic.perform_audit! }.to change{ Delayed::Job.jobs_count(:current) }.by(1)
520
+ expect { Delayed::Periodic.perform_audit! }.to change { Delayed::Job.jobs_count(:current) }.by(1)
440
521
  end
441
522
 
442
- it "should not schedule jobs that are already scheduled" do
443
- Delayed::Job.jobs_count(:current).should == 0
523
+ it "does not schedule jobs that are already scheduled" do
524
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
444
525
  Delayed::Periodic.perform_audit!
445
- Delayed::Job.jobs_count(:current).should == 1
526
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
446
527
  job = Delayed::Job.find_available(1).first
447
528
  Delayed::Periodic.perform_audit!
448
- Delayed::Job.jobs_count(:current).should == 1
529
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
449
530
  # verify that the same job still exists, it wasn't just replaced with a new one
450
- job.should == Delayed::Job.find_available(1).first
531
+ expect(job).to eq(Delayed::Job.find_available(1).first)
451
532
  end
452
533
 
453
- it "should schedule the next job run after performing" do
454
- Delayed::Job.jobs_count(:current).should == 0
534
+ it "schedules the next job run after performing" do
535
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
455
536
  Delayed::Periodic.perform_audit!
456
- Delayed::Job.jobs_count(:current).should == 1
457
- job = Delayed::Job.get_and_lock_next_available('test')
537
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
538
+ job = Delayed::Job.get_and_lock_next_available("test")
458
539
  run_job(job)
459
540
 
460
- job = Delayed::Job.get_and_lock_next_available('test1')
461
- job.tag.should == 'SimpleJob#perform'
541
+ job = Delayed::Job.get_and_lock_next_available("test1")
542
+ expect(job.tag).to eq("SimpleJob#perform")
462
543
 
463
- next_scheduled = Delayed::Job.get_and_lock_next_available('test2')
464
- next_scheduled.tag.should == 'periodic: my SimpleJob'
465
- next_scheduled.payload_object.should be_is_a(Delayed::Periodic)
544
+ next_scheduled = Delayed::Job.get_and_lock_next_available("test2")
545
+ expect(next_scheduled.tag).to eq("periodic: my SimpleJob")
546
+ expect(next_scheduled.payload_object).to be_is_a(Delayed::Periodic)
466
547
  end
467
548
 
468
- it "should reject duplicate named jobs" do
469
- proc { Delayed::Periodic.cron('my SimpleJob', '*/15 * * * * *') {} }.should raise_error(ArgumentError)
549
+ it "rejects duplicate named jobs" do
550
+ expect { Delayed::Periodic.cron("my SimpleJob", "*/15 * * * * *") { nil } }.to raise_error(ArgumentError)
470
551
  end
471
552
 
472
- it "should handle jobs that are no longer scheduled" do
553
+ it "handles jobs that are no longer scheduled" do
473
554
  Delayed::Periodic.perform_audit!
474
555
  Delayed::Periodic.scheduled = {}
475
- job = Delayed::Job.get_and_lock_next_available('test')
556
+ job = Delayed::Job.get_and_lock_next_available("test")
476
557
  run_job(job)
477
558
  # shouldn't error, and the job should now be deleted
478
- Delayed::Job.jobs_count(:current).should == 0
559
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
479
560
  end
480
561
 
481
- it "should allow overriding schedules using periodic_jobs.yml" do
482
- change_setting(Delayed::Periodic, :overrides, { 'my ChangedJob' => '*/10 * * * * *' }) do
562
+ it "allows overriding schedules using periodic_jobs.yml" do
563
+ change_setting(Delayed::Periodic, :overrides, { "my ChangedJob" => "*/10 * * * * *" }) do
483
564
  Delayed::Periodic.scheduled = {}
484
- Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
565
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
485
566
  Delayed::Job.enqueue(SimpleJob.new)
486
567
  end
487
- Delayed::Periodic.scheduled['my ChangedJob'].cron.original.should == '*/10 * * * * *'
568
+ expect(Delayed::Periodic.scheduled["my ChangedJob"].cron.original).to eq("*/10 * * * * *")
488
569
  end
489
570
  end
490
571
 
491
- it "should fail if the override cron line is invalid" do
492
- change_setting(Delayed::Periodic, :overrides, { 'my ChangedJob' => '*/10 * * * * * *' }) do # extra asterisk
572
+ it "fails if the override cron line is invalid" do
573
+ change_setting(Delayed::Periodic, :overrides, { "my ChangedJob" => "*/10 * * * * * *" }) do # extra asterisk
493
574
  Delayed::Periodic.scheduled = {}
494
- expect { Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
495
- Delayed::Job.enqueue(SimpleJob.new)
496
- end }.to raise_error(ArgumentError)
575
+ expect do
576
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
577
+ Delayed::Job.enqueue(SimpleJob.new)
578
+ end
579
+ end.to raise_error(ArgumentError)
497
580
  end
498
581
 
499
- expect { Delayed::Periodic.add_overrides({ 'my ChangedJob' => '*/10 * * * * * *' }) }.to raise_error(ArgumentError)
500
- end
501
- end
502
-
503
- module InDelayedJobTest
504
- def self.check_in_job
505
- Delayed::Job.in_delayed_job?.should == true
582
+ expect do
583
+ Delayed::Periodic.add_overrides({ "my ChangedJob" => "*/10 * * * * * *" })
584
+ end.to raise_error(ArgumentError)
506
585
  end
507
586
  end
508
587
 
509
- it "should set in_delayed_job?" do
588
+ it "sets in_delayed_job?" do
510
589
  job = InDelayedJobTest.delay(ignore_transaction: true).check_in_job
511
- Delayed::Job.in_delayed_job?.should == false
590
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
512
591
  job.invoke_job
513
- Delayed::Job.in_delayed_job?.should == false
592
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
514
593
  end
515
594
 
516
- it "should fail on job creation if an unsaved AR object is used" do
517
- story = Story.new :text => "Once upon..."
518
- lambda { story.delay.text }.should raise_error(RuntimeError)
595
+ it "fails on job creation if an unsaved AR object is used" do
596
+ story = Story.new text: "Once upon..."
597
+ expect { story.delay.text }.to raise_error(RuntimeError)
519
598
 
520
599
  reader = StoryReader.new
521
- lambda { reader.delay.read(story) }.should raise_error(RuntimeError)
600
+ expect { reader.delay.read(story) }.to raise_error(RuntimeError)
522
601
 
523
- lambda { [story, 1, story, false].delay.first }.should raise_error(RuntimeError)
602
+ expect { [story, 1, story, false].delay.first }.to raise_error(RuntimeError)
524
603
  end
525
604
 
526
605
  # the sort order of current_jobs and list_jobs depends on the back-end
@@ -528,62 +607,62 @@ shared_examples_for 'a backend' do
528
607
  describe "current jobs, queue size, strand_size" do
529
608
  before do
530
609
  @jobs = []
531
- 3.times { @jobs << create_job(:priority => 3) }
532
- @jobs.unshift create_job(:priority => 2)
533
- @jobs.unshift create_job(:priority => 1)
534
- @jobs << create_job(:priority => 3, :strand => "test1")
535
- @future_job = create_job(:run_at => 5.hours.from_now)
536
- 2.times { @jobs << create_job(:priority => 3) }
537
- @jobs << create_job(:priority => 3, :strand => "test1")
538
- @failed_job = create_job.tap { |j| j.fail! }
539
- @other_queue_job = create_job(:queue => "another")
610
+ 3.times { @jobs << create_job(priority: 3) }
611
+ @jobs.unshift create_job(priority: 2)
612
+ @jobs.unshift create_job(priority: 1)
613
+ @jobs << create_job(priority: 3, strand: "test1")
614
+ @future_job = create_job(run_at: 5.hours.from_now)
615
+ 2.times { @jobs << create_job(priority: 3) }
616
+ @jobs << create_job(priority: 3, strand: "test1")
617
+ @failed_job = create_job.tap(&:fail!)
618
+ @other_queue_job = create_job(queue: "another")
540
619
  end
541
620
 
542
- it "should return the queued jobs" do
543
- Delayed::Job.list_jobs(:current, 100).map(&:id).sort.should == @jobs.map(&:id).sort
621
+ it "returns the queued jobs" do
622
+ expect(Delayed::Job.list_jobs(:current, 100).map(&:id).sort).to eq(@jobs.map(&:id).sort)
544
623
  end
545
624
 
546
- it "should paginate the returned jobs" do
625
+ it "paginates the returned jobs" do
547
626
  @returned = []
548
627
  @returned += Delayed::Job.list_jobs(:current, 3, 0)
549
628
  @returned += Delayed::Job.list_jobs(:current, 4, 3)
550
629
  @returned += Delayed::Job.list_jobs(:current, 100, 7)
551
- @returned.sort_by { |j| j.id }.should == @jobs.sort_by { |j| j.id }
630
+ expect(@returned.sort_by(&:id)).to eq(@jobs.sort_by(&:id))
552
631
  end
553
632
 
554
- it "should return other queues" do
555
- Delayed::Job.list_jobs(:current, 5, 0, "another").should == [@other_queue_job]
633
+ it "returns other queues" do
634
+ expect(Delayed::Job.list_jobs(:current, 5, 0, "another")).to eq([@other_queue_job])
556
635
  end
557
636
 
558
- it "should return queue size" do
559
- Delayed::Job.jobs_count(:current).should == @jobs.size
560
- Delayed::Job.jobs_count(:current, "another").should == 1
561
- Delayed::Job.jobs_count(:current, "bogus").should == 0
637
+ it "returns queue size" do
638
+ expect(Delayed::Job.jobs_count(:current)).to eq(@jobs.size)
639
+ expect(Delayed::Job.jobs_count(:current, "another")).to eq(1)
640
+ expect(Delayed::Job.jobs_count(:current, "bogus")).to eq(0)
562
641
  end
563
642
 
564
- it "should return strand size" do
565
- Delayed::Job.strand_size("test1").should == 2
566
- Delayed::Job.strand_size("bogus").should == 0
643
+ it "returns strand size" do
644
+ expect(Delayed::Job.strand_size("test1")).to eq(2)
645
+ expect(Delayed::Job.strand_size("bogus")).to eq(0)
567
646
  end
568
647
  end
569
648
 
570
- it "should return the jobs in a strand" do
649
+ it "returns the jobs in a strand" do
571
650
  strand_jobs = []
572
- 3.times { strand_jobs << create_job(:strand => 'test1') }
573
- 2.times { create_job(:strand => 'test2') }
574
- strand_jobs << create_job(:strand => 'test1', :run_at => 5.hours.from_now)
651
+ 3.times { strand_jobs << create_job(strand: "test1") }
652
+ 2.times { create_job(strand: "test2") }
653
+ strand_jobs << create_job(strand: "test1", run_at: 5.hours.from_now)
575
654
  create_job
576
655
 
577
656
  jobs = Delayed::Job.list_jobs(:strand, 3, 0, "test1")
578
- jobs.size.should == 3
657
+ expect(jobs.size).to eq(3)
579
658
 
580
659
  jobs += Delayed::Job.list_jobs(:strand, 3, 3, "test1")
581
- jobs.size.should == 4
660
+ expect(jobs.size).to eq(4)
582
661
 
583
- jobs.sort_by { |j| j.id }.should == strand_jobs.sort_by { |j| j.id }
662
+ expect(jobs.sort_by(&:id)).to eq(strand_jobs.sort_by(&:id))
584
663
  end
585
664
 
586
- it "should return the jobs for a tag" do
665
+ it "returns the jobs for a tag" do
587
666
  tag_jobs = []
588
667
  3.times { tag_jobs << "test".delay(ignore_transaction: true).to_s }
589
668
  2.times { "test".delay.to_i }
@@ -593,62 +672,62 @@ shared_examples_for 'a backend' do
593
672
  create_job
594
673
 
595
674
  jobs = Delayed::Job.list_jobs(:tag, 3, 0, "String#to_s")
596
- jobs.size.should == 3
675
+ expect(jobs.size).to eq(3)
597
676
 
598
677
  jobs += Delayed::Job.list_jobs(:tag, 3, 3, "String#to_s")
599
- jobs.size.should == 5
678
+ expect(jobs.size).to eq(5)
600
679
 
601
- jobs.sort_by { |j| j.id }.should == tag_jobs.sort_by { |j| j.id }
680
+ expect(jobs.sort_by(&:id)).to eq(tag_jobs.sort_by(&:id))
602
681
  end
603
682
 
604
683
  describe "running_jobs" do
605
- it "should return the running jobs, ordered by locked_at" do
684
+ it "returns the running jobs, ordered by locked_at" do
606
685
  Timecop.freeze(10.minutes.ago) { 3.times { create_job } }
607
- j1 = Timecop.freeze(2.minutes.ago) { Delayed::Job.get_and_lock_next_available('w1') }
608
- j2 = Timecop.freeze(5.minutes.ago) { Delayed::Job.get_and_lock_next_available('w2') }
609
- j3 = Timecop.freeze(5.seconds.ago) { Delayed::Job.get_and_lock_next_available('w3') }
610
- [j1, j2, j3].compact.size.should == 3
686
+ j1 = Timecop.freeze(2.minutes.ago) { Delayed::Job.get_and_lock_next_available("w1") }
687
+ j2 = Timecop.freeze(5.minutes.ago) { Delayed::Job.get_and_lock_next_available("w2") }
688
+ j3 = Timecop.freeze(5.seconds.ago) { Delayed::Job.get_and_lock_next_available("w3") }
689
+ expect([j1, j2, j3].compact.size).to eq(3)
611
690
 
612
- Delayed::Job.running_jobs.should == [j2, j1, j3]
691
+ expect(Delayed::Job.running_jobs).to eq([j2, j1, j3])
613
692
  end
614
693
  end
615
694
 
616
695
  describe "future jobs" do
617
- it "should find future jobs once their run_at rolls by" do
618
- Timecop.freeze {
619
- @job = create_job :run_at => 5.minutes.from_now
696
+ it "finds future jobs once their run_at rolls by" do
697
+ Timecop.freeze do
698
+ @job = create_job run_at: 5.minutes.from_now
620
699
  expect(Delayed::Job.find_available(5)).not_to include(@job)
621
- }
622
- Timecop.freeze(1.hour.from_now) {
700
+ end
701
+ Timecop.freeze(1.hour.from_now) do
623
702
  expect(Delayed::Job.find_available(5)).to include(@job)
624
- Delayed::Job.get_and_lock_next_available('test').should == @job
625
- }
703
+ expect(Delayed::Job.get_and_lock_next_available("test")).to eq(@job)
704
+ end
626
705
  end
627
706
 
628
- it "should return future jobs sorted by their run_at" do
707
+ it "returns future jobs sorted by their run_at" do
629
708
  @j1 = create_job
630
- @j2 = create_job :run_at => 1.hour.from_now
631
- @j3 = create_job :run_at => 30.minutes.from_now
632
- Delayed::Job.list_jobs(:future, 1).should == [@j3]
633
- Delayed::Job.list_jobs(:future, 5).should == [@j3, @j2]
634
- Delayed::Job.list_jobs(:future, 1, 1).should == [@j2]
709
+ @j2 = create_job run_at: 1.hour.from_now
710
+ @j3 = create_job run_at: 30.minutes.from_now
711
+ expect(Delayed::Job.list_jobs(:future, 1)).to eq([@j3])
712
+ expect(Delayed::Job.list_jobs(:future, 5)).to eq([@j3, @j2])
713
+ expect(Delayed::Job.list_jobs(:future, 1, 1)).to eq([@j2])
635
714
  end
636
715
  end
637
716
 
638
717
  describe "failed jobs" do
639
718
  # the sort order of failed_jobs depends on the back-end implementation,
640
719
  # so sort order isn't tested here
641
- it "should return the list of failed jobs" do
720
+ it "returns the list of failed jobs" do
642
721
  jobs = []
643
- 3.times { jobs << create_job(:priority => 3) }
644
- jobs = jobs.sort_by { |j| j.id }
645
- Delayed::Job.list_jobs(:failed, 1).should == []
722
+ 3.times { jobs << create_job(priority: 3) }
723
+ jobs = jobs.sort_by(&:id)
724
+ expect(Delayed::Job.list_jobs(:failed, 1)).to eq([])
646
725
  jobs[0].fail!
647
726
  jobs[1].fail!
648
- failed = (Delayed::Job.list_jobs(:failed, 1, 0) + Delayed::Job.list_jobs(:failed, 1, 1)).sort_by { |j| j.id }
649
- failed.size.should == 2
650
- failed[0].original_job_id.should == jobs[0].id
651
- failed[1].original_job_id.should == jobs[1].id
727
+ failed = (Delayed::Job.list_jobs(:failed, 1, 0) + Delayed::Job.list_jobs(:failed, 1, 1)).sort_by(&:id)
728
+ expect(failed.size).to eq(2)
729
+ expect(failed[0].original_job_id).to eq(jobs[0].id)
730
+ expect(failed[1].original_job_id).to eq(jobs[1].id)
652
731
  end
653
732
  end
654
733
 
@@ -659,126 +738,123 @@ shared_examples_for 'a backend' do
659
738
  @ignored_jobs = []
660
739
  end
661
740
 
662
- it "should hold and unhold a scope of jobs" do
663
- @affected_jobs.all? { |j| j.on_hold? }.should be false
664
- @ignored_jobs.any? { |j| j.on_hold? }.should be false
665
- Delayed::Job.bulk_update('hold', :flavor => @flavor, :query => @query).should == @affected_jobs.size
741
+ it "holds and unhold a scope of jobs" do
742
+ expect(@affected_jobs.all?(&:on_hold?)).to be false
743
+ expect(@ignored_jobs.any?(&:on_hold?)).to be false
744
+ expect(Delayed::Job.bulk_update("hold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
666
745
 
667
- @affected_jobs.all? { |j| Delayed::Job.find(j.id).on_hold? }.should be true
668
- @ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
746
+ expect(@affected_jobs.all? { |j| Delayed::Job.find(j.id).on_hold? }).to be true
747
+ expect(@ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
669
748
 
670
- # redis holding seems busted - it removes from the tag set and strand list, so you can't use a query
671
- # to un-hold them
672
- next if Delayed::Job == Delayed::Backend::Redis::Job
673
- Delayed::Job.bulk_update('unhold', :flavor => @flavor, :query => @query).should == @affected_jobs.size
749
+ expect(Delayed::Job.bulk_update("unhold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
674
750
 
675
- @affected_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
676
- @ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
751
+ expect(@affected_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
752
+ expect(@ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
677
753
  end
678
754
 
679
- it "should delete a scope of jobs" do
680
- Delayed::Job.bulk_update('destroy', :flavor => @flavor, :query => @query).should == @affected_jobs.size
681
- @affected_jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.should be_blank
682
- @ignored_jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.size.should == @ignored_jobs.size
755
+ it "deletes a scope of jobs" do
756
+ expect(Delayed::Job.bulk_update("destroy", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
757
+ expect(Delayed::Job.where(id: @affected_jobs.map(&:id))).not_to exist
758
+ expect(Delayed::Job.where(id: @ignored_jobs.map(&:id)).count).to eq @ignored_jobs.size
683
759
  end
684
760
  end
685
761
 
686
762
  describe "scope: current" do
687
763
  include_examples "scope"
688
- before do
689
- @flavor = 'current'
764
+ before do # rubocop:disable RSpec/HooksBeforeExamples
765
+ @flavor = "current"
690
766
  Timecop.freeze(5.minutes.ago) do
691
767
  3.times { @affected_jobs << create_job }
692
- @ignored_jobs << create_job(:run_at => 2.hours.from_now)
693
- @ignored_jobs << create_job(:queue => 'q2')
768
+ @ignored_jobs << create_job(run_at: 2.hours.from_now)
769
+ @ignored_jobs << create_job(queue: "q2")
694
770
  end
695
771
  end
696
772
  end
697
773
 
698
774
  describe "scope: future" do
699
775
  include_examples "scope"
700
- before do
701
- @flavor = 'future'
776
+ before do # rubocop:disable RSpec/HooksBeforeExamples
777
+ @flavor = "future"
702
778
  Timecop.freeze(5.minutes.ago) do
703
- 3.times { @affected_jobs << create_job(:run_at => 2.hours.from_now) }
779
+ 3.times { @affected_jobs << create_job(run_at: 2.hours.from_now) }
704
780
  @ignored_jobs << create_job
705
- @ignored_jobs << create_job(:queue => 'q2', :run_at => 2.hours.from_now)
781
+ @ignored_jobs << create_job(queue: "q2", run_at: 2.hours.from_now)
706
782
  end
707
783
  end
708
784
  end
709
785
 
710
786
  describe "scope: strand" do
711
787
  include_examples "scope"
712
- before do
713
- @flavor = 'strand'
714
- @query = 's1'
788
+ before do # rubocop:disable RSpec/HooksBeforeExamples
789
+ @flavor = "strand"
790
+ @query = "s1"
715
791
  Timecop.freeze(5.minutes.ago) do
716
- @affected_jobs << create_job(:strand => 's1')
717
- @affected_jobs << create_job(:strand => 's1', :run_at => 2.hours.from_now)
792
+ @affected_jobs << create_job(strand: "s1")
793
+ @affected_jobs << create_job(strand: "s1", run_at: 2.hours.from_now)
718
794
  @ignored_jobs << create_job
719
- @ignored_jobs << create_job(:strand => 's2')
720
- @ignored_jobs << create_job(:strand => 's2', :run_at => 2.hours.from_now)
795
+ @ignored_jobs << create_job(strand: "s2")
796
+ @ignored_jobs << create_job(strand: "s2", run_at: 2.hours.from_now)
721
797
  end
722
798
  end
723
799
  end
724
800
 
725
801
  describe "scope: tag" do
726
802
  include_examples "scope"
727
- before do
728
- @flavor = 'tag'
729
- @query = 'String#to_i'
803
+ before do # rubocop:disable RSpec/HooksBeforeExamples
804
+ @flavor = "tag"
805
+ @query = "String#to_i"
730
806
  Timecop.freeze(5.minutes.ago) do
731
807
  @affected_jobs << "test".delay(ignore_transaction: true).to_i
732
- @affected_jobs << "test".delay(strand: 's1', ignore_transaction: true).to_i
808
+ @affected_jobs << "test".delay(strand: "s1", ignore_transaction: true).to_i
733
809
  @affected_jobs << "test".delay(run_at: 2.hours.from_now, ignore_transaction: true).to_i
734
810
  @ignored_jobs << create_job
735
- @ignored_jobs << create_job(:run_at => 1.hour.from_now)
811
+ @ignored_jobs << create_job(run_at: 1.hour.from_now)
736
812
  end
737
813
  end
738
814
  end
739
815
 
740
- it "should hold and un-hold given job ids" do
816
+ it "holds and un-hold given job ids" do
741
817
  j1 = "test".delay(ignore_transaction: true).to_i
742
- j2 = create_job(:run_at => 2.hours.from_now)
743
- j3 = "test".delay(strand: 's1', ignore_transaction: true).to_i
744
- Delayed::Job.bulk_update('hold', :ids => [j1.id, j2.id]).should == 2
745
- Delayed::Job.find(j1.id).on_hold?.should be true
746
- Delayed::Job.find(j2.id).on_hold?.should be true
747
- Delayed::Job.find(j3.id).on_hold?.should be false
818
+ j2 = create_job(run_at: 2.hours.from_now)
819
+ j3 = "test".delay(strand: "s1", ignore_transaction: true).to_i
820
+ expect(Delayed::Job.bulk_update("hold", ids: [j1.id, j2.id])).to eq(2)
821
+ expect(Delayed::Job.find(j1.id).on_hold?).to be true
822
+ expect(Delayed::Job.find(j2.id).on_hold?).to be true
823
+ expect(Delayed::Job.find(j3.id).on_hold?).to be false
748
824
 
749
- Delayed::Job.bulk_update('unhold', :ids => [j2.id, j3.id]).should == 1
750
- Delayed::Job.find(j1.id).on_hold?.should be true
751
- Delayed::Job.find(j2.id).on_hold?.should be false
752
- Delayed::Job.find(j3.id).on_hold?.should be false
825
+ expect(Delayed::Job.bulk_update("unhold", ids: [j2.id, j3.id])).to eq(1)
826
+ expect(Delayed::Job.find(j1.id).on_hold?).to be true
827
+ expect(Delayed::Job.find(j2.id).on_hold?).to be false
828
+ expect(Delayed::Job.find(j3.id).on_hold?).to be false
753
829
  end
754
830
 
755
- it "should not hold locked jobs" do
756
- job1 = Delayed::Job.new(:tag => 'tag')
831
+ it "does not hold locked jobs" do
832
+ job1 = Delayed::Job.new(tag: "tag")
757
833
  job1.create_and_lock!("worker")
758
- job1.on_hold?.should be false
759
- Delayed::Job.bulk_update('hold', ids: [job1.id]).should == 0
760
- Delayed::Job.find(job1.id).on_hold?.should be false
834
+ expect(job1.on_hold?).to be false
835
+ expect(Delayed::Job.bulk_update("hold", ids: [job1.id])).to eq(0)
836
+ expect(Delayed::Job.find(job1.id).on_hold?).to be false
761
837
  end
762
838
 
763
- it "should not unhold locked jobs" do
764
- job1 = Delayed::Job.new(:tag => 'tag')
839
+ it "does not unhold locked jobs" do
840
+ job1 = Delayed::Job.new(tag: "tag")
765
841
  job1.create_and_lock!("worker")
766
- Delayed::Job.bulk_update('unhold', ids: [job1.id]).should == 0
767
- Delayed::Job.find(job1.id).on_hold?.should be false
768
- Delayed::Job.find(job1.id).locked?.should be true
842
+ expect(Delayed::Job.bulk_update("unhold", ids: [job1.id])).to eq(0)
843
+ expect(Delayed::Job.find(job1.id).on_hold?).to be false
844
+ expect(Delayed::Job.find(job1.id).locked?).to be true
769
845
  end
770
846
 
771
- it "should delete given job ids" do
847
+ it "deletes given job ids" do
772
848
  jobs = (0..2).map { create_job }
773
- Delayed::Job.bulk_update('destroy', :ids => jobs[0,2].map(&:id)).should == 2
774
- jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.should == jobs[2,1]
849
+ expect(Delayed::Job.bulk_update("destroy", ids: jobs[0, 2].map(&:id))).to eq(2)
850
+ expect(Delayed::Job.order(:id).where(id: jobs.map(&:id))).to eq jobs[2, 1]
775
851
  end
776
852
 
777
- it "should not delete locked jobs" do
778
- job1 = Delayed::Job.new(:tag => 'tag')
853
+ it "does not delete locked jobs" do
854
+ job1 = Delayed::Job.new(tag: "tag")
779
855
  job1.create_and_lock!("worker")
780
- Delayed::Job.bulk_update('destroy', ids: [job1.id]).should == 0
781
- Delayed::Job.find(job1.id).locked?.should be true
856
+ expect(Delayed::Job.bulk_update("destroy", ids: [job1.id])).to eq(0)
857
+ expect(Delayed::Job.find(job1.id).locked?).to be true
782
858
  end
783
859
  end
784
860
 
@@ -786,7 +862,7 @@ shared_examples_for 'a backend' do
786
862
  before do
787
863
  @cur = []
788
864
  3.times { @cur << "test".delay(ignore_transaction: true).to_s }
789
- 5.times { @cur << "test".delay(ignore_transaction: true).to_i}
865
+ 5.times { @cur << "test".delay(ignore_transaction: true).to_i }
790
866
  2.times { @cur << "test".delay(ignore_transaction: true).upcase }
791
867
  "test".delay(ignore_transaction: true).downcase.fail!
792
868
  @future = []
@@ -794,48 +870,48 @@ shared_examples_for 'a backend' do
794
870
  @cur << "test".delay(ignore_transaction: true).downcase
795
871
  end
796
872
 
797
- it "should return a sorted list of popular current tags" do
798
- Delayed::Job.tag_counts(:current, 1).should == [{ :tag => "String#to_i", :count => 5 }]
799
- Delayed::Job.tag_counts(:current, 1, 1).should == [{ :tag => "String#to_s", :count => 3 }]
800
- Delayed::Job.tag_counts(:current, 5).should == [{ :tag => "String#to_i", :count => 5 },
801
- { :tag => "String#to_s", :count => 3 },
802
- { :tag => "String#upcase", :count => 2 },
803
- { :tag => "String#downcase", :count => 1 }]
804
- @cur[0,4].each { |j| j.destroy }
873
+ it "returns a sorted list of popular current tags" do
874
+ expect(Delayed::Job.tag_counts(:current, 1)).to eq([{ tag: "String#to_i", count: 5 }])
875
+ expect(Delayed::Job.tag_counts(:current, 1, 1)).to eq([{ tag: "String#to_s", count: 3 }])
876
+ expect(Delayed::Job.tag_counts(:current, 5)).to eq([{ tag: "String#to_i", count: 5 },
877
+ { tag: "String#to_s", count: 3 },
878
+ { tag: "String#upcase", count: 2 },
879
+ { tag: "String#downcase", count: 1 }])
880
+ @cur[0, 4].each(&:destroy)
805
881
  @future[0].run_at = @future[1].run_at = 1.hour.ago
806
882
  @future[0].save!
807
883
  @future[1].save!
808
884
 
809
- Delayed::Job.tag_counts(:current, 5).should == [{ :tag => "String#to_i", :count => 4 },
810
- { :tag => "String#downcase", :count => 3 },
811
- { :tag => "String#upcase", :count => 2 },]
885
+ expect(Delayed::Job.tag_counts(:current, 5)).to eq([{ tag: "String#to_i", count: 4 },
886
+ { tag: "String#downcase", count: 3 },
887
+ { tag: "String#upcase", count: 2 }])
812
888
  end
813
889
 
814
- it "should return a sorted list of all popular tags" do
815
- Delayed::Job.tag_counts(:all, 1).should == [{ :tag => "String#downcase", :count => 6 }]
816
- Delayed::Job.tag_counts(:all, 1, 1).should == [{ :tag => "String#to_i", :count => 5 }]
817
- Delayed::Job.tag_counts(:all, 5).should == [{ :tag => "String#downcase", :count => 6 },
818
- { :tag => "String#to_i", :count => 5 },
819
- { :tag => "String#to_s", :count => 3 },
820
- { :tag => "String#upcase", :count => 2 },]
890
+ it "returns a sorted list of all popular tags" do
891
+ expect(Delayed::Job.tag_counts(:all, 1)).to eq([{ tag: "String#downcase", count: 6 }])
892
+ expect(Delayed::Job.tag_counts(:all, 1, 1)).to eq([{ tag: "String#to_i", count: 5 }])
893
+ expect(Delayed::Job.tag_counts(:all, 5)).to eq([{ tag: "String#downcase", count: 6 },
894
+ { tag: "String#to_i", count: 5 },
895
+ { tag: "String#to_s", count: 3 },
896
+ { tag: "String#upcase", count: 2 }])
821
897
 
822
- @cur[0,4].each { |j| j.destroy }
898
+ @cur[0, 4].each(&:destroy)
823
899
  @future[0].destroy
824
900
  @future[1].fail!
825
901
  @future[2].fail!
826
902
 
827
- Delayed::Job.tag_counts(:all, 5).should == [{ :tag => "String#to_i", :count => 4 },
828
- { :tag => "String#downcase", :count => 3 },
829
- { :tag => "String#upcase", :count => 2 },]
903
+ expect(Delayed::Job.tag_counts(:all, 5)).to eq([{ tag: "String#to_i", count: 4 },
904
+ { tag: "String#downcase", count: 3 },
905
+ { tag: "String#upcase", count: 2 }])
830
906
  end
831
907
  end
832
908
 
833
- it "should unlock orphaned jobs" do
909
+ it "unlocks orphaned jobs" do
834
910
  change_setting(Delayed::Settings, :max_attempts, 2) do
835
- job1 = Delayed::Job.new(:tag => 'tag')
836
- job2 = Delayed::Job.new(:tag => 'tag')
837
- job3 = Delayed::Job.new(:tag => 'tag')
838
- job4 = Delayed::Job.new(:tag => 'tag')
911
+ job1 = Delayed::Job.new(tag: "tag")
912
+ job2 = Delayed::Job.new(tag: "tag")
913
+ job3 = Delayed::Job.new(tag: "tag")
914
+ job4 = Delayed::Job.new(tag: "tag")
839
915
  job1.create_and_lock!("Jobworker:#{Process.pid}")
840
916
  `echo ''`
841
917
  child_pid = $?.pid
@@ -843,23 +919,23 @@ shared_examples_for 'a backend' do
843
919
  job3.create_and_lock!("someoneelse:#{Process.pid}")
844
920
  job4.create_and_lock!("Jobworker:notanumber")
845
921
 
846
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 1
922
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(1)
847
923
 
848
- Delayed::Job.find(job1.id).locked_by.should_not be_nil
849
- Delayed::Job.find(job2.id).locked_by.should be_nil
850
- Delayed::Job.find(job3.id).locked_by.should_not be_nil
851
- Delayed::Job.find(job4.id).locked_by.should_not be_nil
924
+ expect(Delayed::Job.find(job1.id).locked_by).not_to be_nil
925
+ expect(Delayed::Job.find(job2.id).locked_by).to be_nil
926
+ expect(Delayed::Job.find(job3.id).locked_by).not_to be_nil
927
+ expect(Delayed::Job.find(job4.id).locked_by).not_to be_nil
852
928
 
853
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 0
929
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(0)
854
930
  end
855
931
  end
856
932
 
857
- it "should unlock orphaned jobs given a pid" do
933
+ it "unlocks orphaned jobs given a pid" do
858
934
  change_setting(Delayed::Settings, :max_attempts, 2) do
859
- job1 = Delayed::Job.new(:tag => 'tag')
860
- job2 = Delayed::Job.new(:tag => 'tag')
861
- job3 = Delayed::Job.new(:tag => 'tag')
862
- job4 = Delayed::Job.new(:tag => 'tag')
935
+ job1 = Delayed::Job.new(tag: "tag")
936
+ job2 = Delayed::Job.new(tag: "tag")
937
+ job3 = Delayed::Job.new(tag: "tag")
938
+ job4 = Delayed::Job.new(tag: "tag")
863
939
  job1.create_and_lock!("Jobworker:#{Process.pid}")
864
940
  `echo ''`
865
941
  child_pid = $?.pid
@@ -869,15 +945,15 @@ shared_examples_for 'a backend' do
869
945
  job3.create_and_lock!("someoneelse:#{Process.pid}")
870
946
  job4.create_and_lock!("Jobworker:notanumber")
871
947
 
872
- Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker").should == 0
873
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 1
948
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker")).to eq(0)
949
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(1)
874
950
 
875
- Delayed::Job.find(job1.id).locked_by.should_not be_nil
876
- Delayed::Job.find(job2.id).locked_by.should be_nil
877
- Delayed::Job.find(job3.id).locked_by.should_not be_nil
878
- Delayed::Job.find(job4.id).locked_by.should_not be_nil
951
+ expect(Delayed::Job.find(job1.id).locked_by).not_to be_nil
952
+ expect(Delayed::Job.find(job2.id).locked_by).to be_nil
953
+ expect(Delayed::Job.find(job3.id).locked_by).not_to be_nil
954
+ expect(Delayed::Job.find(job4.id).locked_by).not_to be_nil
879
955
 
880
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 0
956
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(0)
881
957
  end
882
958
  end
883
959
  end