inst-jobs 2.3.2 → 2.4.2

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 +12 -0
  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 +16 -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 +534 -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 +75 -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,393 @@ 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
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
395
493
  end
396
494
  end
397
495
  end
398
496
 
399
497
  context "on hold" do
400
- it "should hold/unhold jobs" do
401
- job1 = create_job()
498
+ it "hold/unholds jobs" do
499
+ job1 = create_job
402
500
  job1.hold!
403
- Delayed::Job.get_and_lock_next_available('w1').should be_nil
501
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
404
502
 
405
503
  job1.unhold!
406
- Delayed::Job.get_and_lock_next_available('w1').should == job1
504
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
407
505
  end
408
506
  end
409
507
 
410
508
  context "periodic jobs" do
411
- before(:each) do
509
+ before do
412
510
  # make the periodic job get scheduled in the past
413
511
  @cron_time = 10.minutes.ago
414
512
  allow(Delayed::Periodic).to receive(:now).and_return(@cron_time)
415
513
  Delayed::Periodic.scheduled = {}
416
- Delayed::Periodic.cron('my SimpleJob', '*/5 * * * * *') do
514
+ Delayed::Periodic.cron("my SimpleJob", "*/5 * * * * *") do
417
515
  Delayed::Job.enqueue(SimpleJob.new)
418
516
  end
419
517
  end
420
518
 
421
- it "should schedule jobs if they aren't scheduled yet" do
422
- Delayed::Job.jobs_count(:current).should == 0
519
+ it "schedules jobs if they aren't scheduled yet" do
520
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
423
521
  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
522
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
523
+ job = Delayed::Job.get_and_lock_next_available("test1")
524
+ expect(job.tag).to eq("periodic: my SimpleJob")
525
+ expect(job.payload_object).to eq(Delayed::Periodic.scheduled["my SimpleJob"])
526
+ expect(job.run_at).to be >= @cron_time
527
+ expect(job.run_at).to be <= @cron_time + 6.minutes
528
+ expect(job.singleton).to eq(job.tag)
431
529
  end
432
530
 
433
- it "should schedule jobs if there are only failed jobs on the queue" do
434
- Delayed::Job.jobs_count(:current).should == 0
531
+ it "schedules jobs if there are only failed jobs on the queue" do
532
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
435
533
  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')
534
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
535
+ job = Delayed::Job.get_and_lock_next_available("test1")
438
536
  job.fail!
439
- expect { Delayed::Periodic.perform_audit! }.to change{ Delayed::Job.jobs_count(:current) }.by(1)
537
+ expect { Delayed::Periodic.perform_audit! }.to change { Delayed::Job.jobs_count(:current) }.by(1)
440
538
  end
441
539
 
442
- it "should not schedule jobs that are already scheduled" do
443
- Delayed::Job.jobs_count(:current).should == 0
540
+ it "does not schedule jobs that are already scheduled" do
541
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
444
542
  Delayed::Periodic.perform_audit!
445
- Delayed::Job.jobs_count(:current).should == 1
543
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
446
544
  job = Delayed::Job.find_available(1).first
447
545
  Delayed::Periodic.perform_audit!
448
- Delayed::Job.jobs_count(:current).should == 1
546
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
449
547
  # 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
548
+ expect(job).to eq(Delayed::Job.find_available(1).first)
451
549
  end
452
550
 
453
- it "should schedule the next job run after performing" do
454
- Delayed::Job.jobs_count(:current).should == 0
551
+ it "schedules the next job run after performing" do
552
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
455
553
  Delayed::Periodic.perform_audit!
456
- Delayed::Job.jobs_count(:current).should == 1
457
- job = Delayed::Job.get_and_lock_next_available('test')
554
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
555
+ job = Delayed::Job.get_and_lock_next_available("test")
458
556
  run_job(job)
459
557
 
460
- job = Delayed::Job.get_and_lock_next_available('test1')
461
- job.tag.should == 'SimpleJob#perform'
558
+ job = Delayed::Job.get_and_lock_next_available("test1")
559
+ expect(job.tag).to eq("SimpleJob#perform")
462
560
 
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)
561
+ next_scheduled = Delayed::Job.get_and_lock_next_available("test2")
562
+ expect(next_scheduled.tag).to eq("periodic: my SimpleJob")
563
+ expect(next_scheduled.payload_object).to be_is_a(Delayed::Periodic)
466
564
  end
467
565
 
468
- it "should reject duplicate named jobs" do
469
- proc { Delayed::Periodic.cron('my SimpleJob', '*/15 * * * * *') {} }.should raise_error(ArgumentError)
566
+ it "rejects duplicate named jobs" do
567
+ expect { Delayed::Periodic.cron("my SimpleJob", "*/15 * * * * *") { nil } }.to raise_error(ArgumentError)
470
568
  end
471
569
 
472
- it "should handle jobs that are no longer scheduled" do
570
+ it "handles jobs that are no longer scheduled" do
473
571
  Delayed::Periodic.perform_audit!
474
572
  Delayed::Periodic.scheduled = {}
475
- job = Delayed::Job.get_and_lock_next_available('test')
573
+ job = Delayed::Job.get_and_lock_next_available("test")
476
574
  run_job(job)
477
575
  # shouldn't error, and the job should now be deleted
478
- Delayed::Job.jobs_count(:current).should == 0
576
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
479
577
  end
480
578
 
481
- it "should allow overriding schedules using periodic_jobs.yml" do
482
- change_setting(Delayed::Periodic, :overrides, { 'my ChangedJob' => '*/10 * * * * *' }) do
579
+ it "allows overriding schedules using periodic_jobs.yml" do
580
+ change_setting(Delayed::Periodic, :overrides, { "my ChangedJob" => "*/10 * * * * *" }) do
483
581
  Delayed::Periodic.scheduled = {}
484
- Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
582
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
485
583
  Delayed::Job.enqueue(SimpleJob.new)
486
584
  end
487
- Delayed::Periodic.scheduled['my ChangedJob'].cron.original.should == '*/10 * * * * *'
585
+ expect(Delayed::Periodic.scheduled["my ChangedJob"].cron.original).to eq("*/10 * * * * *")
488
586
  end
489
587
  end
490
588
 
491
- it "should fail if the override cron line is invalid" do
492
- change_setting(Delayed::Periodic, :overrides, { 'my ChangedJob' => '*/10 * * * * * *' }) do # extra asterisk
589
+ it "fails if the override cron line is invalid" do
590
+ change_setting(Delayed::Periodic, :overrides, { "my ChangedJob" => "*/10 * * * * * *" }) do # extra asterisk
493
591
  Delayed::Periodic.scheduled = {}
494
- expect { Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
495
- Delayed::Job.enqueue(SimpleJob.new)
496
- end }.to raise_error(ArgumentError)
592
+ expect do
593
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
594
+ Delayed::Job.enqueue(SimpleJob.new)
595
+ end
596
+ end.to raise_error(ArgumentError)
497
597
  end
498
598
 
499
- expect { Delayed::Periodic.add_overrides({ 'my ChangedJob' => '*/10 * * * * * *' }) }.to raise_error(ArgumentError)
599
+ expect do
600
+ Delayed::Periodic.add_overrides({ "my ChangedJob" => "*/10 * * * * * *" })
601
+ end.to raise_error(ArgumentError)
500
602
  end
501
603
  end
502
604
 
503
- module InDelayedJobTest
504
- def self.check_in_job
505
- Delayed::Job.in_delayed_job?.should == true
506
- end
507
- end
508
-
509
- it "should set in_delayed_job?" do
605
+ it "sets in_delayed_job?" do
510
606
  job = InDelayedJobTest.delay(ignore_transaction: true).check_in_job
511
- Delayed::Job.in_delayed_job?.should == false
607
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
512
608
  job.invoke_job
513
- Delayed::Job.in_delayed_job?.should == false
609
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
514
610
  end
515
611
 
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)
612
+ it "fails on job creation if an unsaved AR object is used" do
613
+ story = Story.new text: "Once upon..."
614
+ expect { story.delay.text }.to raise_error(RuntimeError)
519
615
 
520
616
  reader = StoryReader.new
521
- lambda { reader.delay.read(story) }.should raise_error(RuntimeError)
617
+ expect { reader.delay.read(story) }.to raise_error(RuntimeError)
522
618
 
523
- lambda { [story, 1, story, false].delay.first }.should raise_error(RuntimeError)
619
+ expect { [story, 1, story, false].delay.first }.to raise_error(RuntimeError)
524
620
  end
525
621
 
526
622
  # the sort order of current_jobs and list_jobs depends on the back-end
@@ -528,62 +624,62 @@ shared_examples_for 'a backend' do
528
624
  describe "current jobs, queue size, strand_size" do
529
625
  before do
530
626
  @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")
627
+ 3.times { @jobs << create_job(priority: 3) }
628
+ @jobs.unshift create_job(priority: 2)
629
+ @jobs.unshift create_job(priority: 1)
630
+ @jobs << create_job(priority: 3, strand: "test1")
631
+ @future_job = create_job(run_at: 5.hours.from_now)
632
+ 2.times { @jobs << create_job(priority: 3) }
633
+ @jobs << create_job(priority: 3, strand: "test1")
634
+ @failed_job = create_job.tap(&:fail!)
635
+ @other_queue_job = create_job(queue: "another")
540
636
  end
541
637
 
542
- it "should return the queued jobs" do
543
- Delayed::Job.list_jobs(:current, 100).map(&:id).sort.should == @jobs.map(&:id).sort
638
+ it "returns the queued jobs" do
639
+ expect(Delayed::Job.list_jobs(:current, 100).map(&:id).sort).to eq(@jobs.map(&:id).sort)
544
640
  end
545
641
 
546
- it "should paginate the returned jobs" do
642
+ it "paginates the returned jobs" do
547
643
  @returned = []
548
644
  @returned += Delayed::Job.list_jobs(:current, 3, 0)
549
645
  @returned += Delayed::Job.list_jobs(:current, 4, 3)
550
646
  @returned += Delayed::Job.list_jobs(:current, 100, 7)
551
- @returned.sort_by { |j| j.id }.should == @jobs.sort_by { |j| j.id }
647
+ expect(@returned.sort_by(&:id)).to eq(@jobs.sort_by(&:id))
552
648
  end
553
649
 
554
- it "should return other queues" do
555
- Delayed::Job.list_jobs(:current, 5, 0, "another").should == [@other_queue_job]
650
+ it "returns other queues" do
651
+ expect(Delayed::Job.list_jobs(:current, 5, 0, "another")).to eq([@other_queue_job])
556
652
  end
557
653
 
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
654
+ it "returns queue size" do
655
+ expect(Delayed::Job.jobs_count(:current)).to eq(@jobs.size)
656
+ expect(Delayed::Job.jobs_count(:current, "another")).to eq(1)
657
+ expect(Delayed::Job.jobs_count(:current, "bogus")).to eq(0)
562
658
  end
563
659
 
564
- it "should return strand size" do
565
- Delayed::Job.strand_size("test1").should == 2
566
- Delayed::Job.strand_size("bogus").should == 0
660
+ it "returns strand size" do
661
+ expect(Delayed::Job.strand_size("test1")).to eq(2)
662
+ expect(Delayed::Job.strand_size("bogus")).to eq(0)
567
663
  end
568
664
  end
569
665
 
570
- it "should return the jobs in a strand" do
666
+ it "returns the jobs in a strand" do
571
667
  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)
668
+ 3.times { strand_jobs << create_job(strand: "test1") }
669
+ 2.times { create_job(strand: "test2") }
670
+ strand_jobs << create_job(strand: "test1", run_at: 5.hours.from_now)
575
671
  create_job
576
672
 
577
673
  jobs = Delayed::Job.list_jobs(:strand, 3, 0, "test1")
578
- jobs.size.should == 3
674
+ expect(jobs.size).to eq(3)
579
675
 
580
676
  jobs += Delayed::Job.list_jobs(:strand, 3, 3, "test1")
581
- jobs.size.should == 4
677
+ expect(jobs.size).to eq(4)
582
678
 
583
- jobs.sort_by { |j| j.id }.should == strand_jobs.sort_by { |j| j.id }
679
+ expect(jobs.sort_by(&:id)).to eq(strand_jobs.sort_by(&:id))
584
680
  end
585
681
 
586
- it "should return the jobs for a tag" do
682
+ it "returns the jobs for a tag" do
587
683
  tag_jobs = []
588
684
  3.times { tag_jobs << "test".delay(ignore_transaction: true).to_s }
589
685
  2.times { "test".delay.to_i }
@@ -593,62 +689,62 @@ shared_examples_for 'a backend' do
593
689
  create_job
594
690
 
595
691
  jobs = Delayed::Job.list_jobs(:tag, 3, 0, "String#to_s")
596
- jobs.size.should == 3
692
+ expect(jobs.size).to eq(3)
597
693
 
598
694
  jobs += Delayed::Job.list_jobs(:tag, 3, 3, "String#to_s")
599
- jobs.size.should == 5
695
+ expect(jobs.size).to eq(5)
600
696
 
601
- jobs.sort_by { |j| j.id }.should == tag_jobs.sort_by { |j| j.id }
697
+ expect(jobs.sort_by(&:id)).to eq(tag_jobs.sort_by(&:id))
602
698
  end
603
699
 
604
700
  describe "running_jobs" do
605
- it "should return the running jobs, ordered by locked_at" do
701
+ it "returns the running jobs, ordered by locked_at" do
606
702
  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
703
+ j1 = Timecop.freeze(2.minutes.ago) { Delayed::Job.get_and_lock_next_available("w1") }
704
+ j2 = Timecop.freeze(5.minutes.ago) { Delayed::Job.get_and_lock_next_available("w2") }
705
+ j3 = Timecop.freeze(5.seconds.ago) { Delayed::Job.get_and_lock_next_available("w3") }
706
+ expect([j1, j2, j3].compact.size).to eq(3)
611
707
 
612
- Delayed::Job.running_jobs.should == [j2, j1, j3]
708
+ expect(Delayed::Job.running_jobs).to eq([j2, j1, j3])
613
709
  end
614
710
  end
615
711
 
616
712
  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
713
+ it "finds future jobs once their run_at rolls by" do
714
+ Timecop.freeze do
715
+ @job = create_job run_at: 5.minutes.from_now
620
716
  expect(Delayed::Job.find_available(5)).not_to include(@job)
621
- }
622
- Timecop.freeze(1.hour.from_now) {
717
+ end
718
+ Timecop.freeze(1.hour.from_now) do
623
719
  expect(Delayed::Job.find_available(5)).to include(@job)
624
- Delayed::Job.get_and_lock_next_available('test').should == @job
625
- }
720
+ expect(Delayed::Job.get_and_lock_next_available("test")).to eq(@job)
721
+ end
626
722
  end
627
723
 
628
- it "should return future jobs sorted by their run_at" do
724
+ it "returns future jobs sorted by their run_at" do
629
725
  @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]
726
+ @j2 = create_job run_at: 1.hour.from_now
727
+ @j3 = create_job run_at: 30.minutes.from_now
728
+ expect(Delayed::Job.list_jobs(:future, 1)).to eq([@j3])
729
+ expect(Delayed::Job.list_jobs(:future, 5)).to eq([@j3, @j2])
730
+ expect(Delayed::Job.list_jobs(:future, 1, 1)).to eq([@j2])
635
731
  end
636
732
  end
637
733
 
638
734
  describe "failed jobs" do
639
735
  # the sort order of failed_jobs depends on the back-end implementation,
640
736
  # so sort order isn't tested here
641
- it "should return the list of failed jobs" do
737
+ it "returns the list of failed jobs" do
642
738
  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 == []
739
+ 3.times { jobs << create_job(priority: 3) }
740
+ jobs = jobs.sort_by(&:id)
741
+ expect(Delayed::Job.list_jobs(:failed, 1)).to eq([])
646
742
  jobs[0].fail!
647
743
  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
744
+ failed = (Delayed::Job.list_jobs(:failed, 1, 0) + Delayed::Job.list_jobs(:failed, 1, 1)).sort_by(&:id)
745
+ expect(failed.size).to eq(2)
746
+ expect(failed[0].original_job_id).to eq(jobs[0].id)
747
+ expect(failed[1].original_job_id).to eq(jobs[1].id)
652
748
  end
653
749
  end
654
750
 
@@ -659,126 +755,123 @@ shared_examples_for 'a backend' do
659
755
  @ignored_jobs = []
660
756
  end
661
757
 
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
758
+ it "holds and unhold a scope of jobs" do
759
+ expect(@affected_jobs.all?(&:on_hold?)).to be false
760
+ expect(@ignored_jobs.any?(&:on_hold?)).to be false
761
+ expect(Delayed::Job.bulk_update("hold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
666
762
 
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
763
+ expect(@affected_jobs.all? { |j| Delayed::Job.find(j.id).on_hold? }).to be true
764
+ expect(@ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
669
765
 
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
766
+ expect(Delayed::Job.bulk_update("unhold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
674
767
 
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
768
+ expect(@affected_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
769
+ expect(@ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }).to be false
677
770
  end
678
771
 
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
772
+ it "deletes a scope of jobs" do
773
+ expect(Delayed::Job.bulk_update("destroy", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
774
+ expect(Delayed::Job.where(id: @affected_jobs.map(&:id))).not_to exist
775
+ expect(Delayed::Job.where(id: @ignored_jobs.map(&:id)).count).to eq @ignored_jobs.size
683
776
  end
684
777
  end
685
778
 
686
779
  describe "scope: current" do
687
780
  include_examples "scope"
688
- before do
689
- @flavor = 'current'
781
+ before do # rubocop:disable RSpec/HooksBeforeExamples
782
+ @flavor = "current"
690
783
  Timecop.freeze(5.minutes.ago) do
691
784
  3.times { @affected_jobs << create_job }
692
- @ignored_jobs << create_job(:run_at => 2.hours.from_now)
693
- @ignored_jobs << create_job(:queue => 'q2')
785
+ @ignored_jobs << create_job(run_at: 2.hours.from_now)
786
+ @ignored_jobs << create_job(queue: "q2")
694
787
  end
695
788
  end
696
789
  end
697
790
 
698
791
  describe "scope: future" do
699
792
  include_examples "scope"
700
- before do
701
- @flavor = 'future'
793
+ before do # rubocop:disable RSpec/HooksBeforeExamples
794
+ @flavor = "future"
702
795
  Timecop.freeze(5.minutes.ago) do
703
- 3.times { @affected_jobs << create_job(:run_at => 2.hours.from_now) }
796
+ 3.times { @affected_jobs << create_job(run_at: 2.hours.from_now) }
704
797
  @ignored_jobs << create_job
705
- @ignored_jobs << create_job(:queue => 'q2', :run_at => 2.hours.from_now)
798
+ @ignored_jobs << create_job(queue: "q2", run_at: 2.hours.from_now)
706
799
  end
707
800
  end
708
801
  end
709
802
 
710
803
  describe "scope: strand" do
711
804
  include_examples "scope"
712
- before do
713
- @flavor = 'strand'
714
- @query = 's1'
805
+ before do # rubocop:disable RSpec/HooksBeforeExamples
806
+ @flavor = "strand"
807
+ @query = "s1"
715
808
  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)
809
+ @affected_jobs << create_job(strand: "s1")
810
+ @affected_jobs << create_job(strand: "s1", run_at: 2.hours.from_now)
718
811
  @ignored_jobs << create_job
719
- @ignored_jobs << create_job(:strand => 's2')
720
- @ignored_jobs << create_job(:strand => 's2', :run_at => 2.hours.from_now)
812
+ @ignored_jobs << create_job(strand: "s2")
813
+ @ignored_jobs << create_job(strand: "s2", run_at: 2.hours.from_now)
721
814
  end
722
815
  end
723
816
  end
724
817
 
725
818
  describe "scope: tag" do
726
819
  include_examples "scope"
727
- before do
728
- @flavor = 'tag'
729
- @query = 'String#to_i'
820
+ before do # rubocop:disable RSpec/HooksBeforeExamples
821
+ @flavor = "tag"
822
+ @query = "String#to_i"
730
823
  Timecop.freeze(5.minutes.ago) do
731
824
  @affected_jobs << "test".delay(ignore_transaction: true).to_i
732
- @affected_jobs << "test".delay(strand: 's1', ignore_transaction: true).to_i
825
+ @affected_jobs << "test".delay(strand: "s1", ignore_transaction: true).to_i
733
826
  @affected_jobs << "test".delay(run_at: 2.hours.from_now, ignore_transaction: true).to_i
734
827
  @ignored_jobs << create_job
735
- @ignored_jobs << create_job(:run_at => 1.hour.from_now)
828
+ @ignored_jobs << create_job(run_at: 1.hour.from_now)
736
829
  end
737
830
  end
738
831
  end
739
832
 
740
- it "should hold and un-hold given job ids" do
833
+ it "holds and un-hold given job ids" do
741
834
  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
835
+ j2 = create_job(run_at: 2.hours.from_now)
836
+ j3 = "test".delay(strand: "s1", ignore_transaction: true).to_i
837
+ expect(Delayed::Job.bulk_update("hold", ids: [j1.id, j2.id])).to eq(2)
838
+ expect(Delayed::Job.find(j1.id).on_hold?).to be true
839
+ expect(Delayed::Job.find(j2.id).on_hold?).to be true
840
+ expect(Delayed::Job.find(j3.id).on_hold?).to be false
748
841
 
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
842
+ expect(Delayed::Job.bulk_update("unhold", ids: [j2.id, j3.id])).to eq(1)
843
+ expect(Delayed::Job.find(j1.id).on_hold?).to be true
844
+ expect(Delayed::Job.find(j2.id).on_hold?).to be false
845
+ expect(Delayed::Job.find(j3.id).on_hold?).to be false
753
846
  end
754
847
 
755
- it "should not hold locked jobs" do
756
- job1 = Delayed::Job.new(:tag => 'tag')
848
+ it "does not hold locked jobs" do
849
+ job1 = Delayed::Job.new(tag: "tag")
757
850
  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
851
+ expect(job1.on_hold?).to be false
852
+ expect(Delayed::Job.bulk_update("hold", ids: [job1.id])).to eq(0)
853
+ expect(Delayed::Job.find(job1.id).on_hold?).to be false
761
854
  end
762
855
 
763
- it "should not unhold locked jobs" do
764
- job1 = Delayed::Job.new(:tag => 'tag')
856
+ it "does not unhold locked jobs" do
857
+ job1 = Delayed::Job.new(tag: "tag")
765
858
  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
859
+ expect(Delayed::Job.bulk_update("unhold", ids: [job1.id])).to eq(0)
860
+ expect(Delayed::Job.find(job1.id).on_hold?).to be false
861
+ expect(Delayed::Job.find(job1.id).locked?).to be true
769
862
  end
770
863
 
771
- it "should delete given job ids" do
864
+ it "deletes given job ids" do
772
865
  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]
866
+ expect(Delayed::Job.bulk_update("destroy", ids: jobs[0, 2].map(&:id))).to eq(2)
867
+ expect(Delayed::Job.order(:id).where(id: jobs.map(&:id))).to eq jobs[2, 1]
775
868
  end
776
869
 
777
- it "should not delete locked jobs" do
778
- job1 = Delayed::Job.new(:tag => 'tag')
870
+ it "does not delete locked jobs" do
871
+ job1 = Delayed::Job.new(tag: "tag")
779
872
  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
873
+ expect(Delayed::Job.bulk_update("destroy", ids: [job1.id])).to eq(0)
874
+ expect(Delayed::Job.find(job1.id).locked?).to be true
782
875
  end
783
876
  end
784
877
 
@@ -786,7 +879,7 @@ shared_examples_for 'a backend' do
786
879
  before do
787
880
  @cur = []
788
881
  3.times { @cur << "test".delay(ignore_transaction: true).to_s }
789
- 5.times { @cur << "test".delay(ignore_transaction: true).to_i}
882
+ 5.times { @cur << "test".delay(ignore_transaction: true).to_i }
790
883
  2.times { @cur << "test".delay(ignore_transaction: true).upcase }
791
884
  "test".delay(ignore_transaction: true).downcase.fail!
792
885
  @future = []
@@ -794,48 +887,48 @@ shared_examples_for 'a backend' do
794
887
  @cur << "test".delay(ignore_transaction: true).downcase
795
888
  end
796
889
 
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 }
890
+ it "returns a sorted list of popular current tags" do
891
+ expect(Delayed::Job.tag_counts(:current, 1)).to eq([{ tag: "String#to_i", count: 5 }])
892
+ expect(Delayed::Job.tag_counts(:current, 1, 1)).to eq([{ tag: "String#to_s", count: 3 }])
893
+ expect(Delayed::Job.tag_counts(:current, 5)).to eq([{ tag: "String#to_i", count: 5 },
894
+ { tag: "String#to_s", count: 3 },
895
+ { tag: "String#upcase", count: 2 },
896
+ { tag: "String#downcase", count: 1 }])
897
+ @cur[0, 4].each(&:destroy)
805
898
  @future[0].run_at = @future[1].run_at = 1.hour.ago
806
899
  @future[0].save!
807
900
  @future[1].save!
808
901
 
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 },]
902
+ expect(Delayed::Job.tag_counts(:current, 5)).to eq([{ tag: "String#to_i", count: 4 },
903
+ { tag: "String#downcase", count: 3 },
904
+ { tag: "String#upcase", count: 2 }])
812
905
  end
813
906
 
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 },]
907
+ it "returns a sorted list of all popular tags" do
908
+ expect(Delayed::Job.tag_counts(:all, 1)).to eq([{ tag: "String#downcase", count: 6 }])
909
+ expect(Delayed::Job.tag_counts(:all, 1, 1)).to eq([{ tag: "String#to_i", count: 5 }])
910
+ expect(Delayed::Job.tag_counts(:all, 5)).to eq([{ tag: "String#downcase", count: 6 },
911
+ { tag: "String#to_i", count: 5 },
912
+ { tag: "String#to_s", count: 3 },
913
+ { tag: "String#upcase", count: 2 }])
821
914
 
822
- @cur[0,4].each { |j| j.destroy }
915
+ @cur[0, 4].each(&:destroy)
823
916
  @future[0].destroy
824
917
  @future[1].fail!
825
918
  @future[2].fail!
826
919
 
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 },]
920
+ expect(Delayed::Job.tag_counts(:all, 5)).to eq([{ tag: "String#to_i", count: 4 },
921
+ { tag: "String#downcase", count: 3 },
922
+ { tag: "String#upcase", count: 2 }])
830
923
  end
831
924
  end
832
925
 
833
- it "should unlock orphaned jobs" do
926
+ it "unlocks orphaned jobs" do
834
927
  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')
928
+ job1 = Delayed::Job.new(tag: "tag")
929
+ job2 = Delayed::Job.new(tag: "tag")
930
+ job3 = Delayed::Job.new(tag: "tag")
931
+ job4 = Delayed::Job.new(tag: "tag")
839
932
  job1.create_and_lock!("Jobworker:#{Process.pid}")
840
933
  `echo ''`
841
934
  child_pid = $?.pid
@@ -843,23 +936,23 @@ shared_examples_for 'a backend' do
843
936
  job3.create_and_lock!("someoneelse:#{Process.pid}")
844
937
  job4.create_and_lock!("Jobworker:notanumber")
845
938
 
846
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 1
939
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(1)
847
940
 
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
941
+ expect(Delayed::Job.find(job1.id).locked_by).not_to be_nil
942
+ expect(Delayed::Job.find(job2.id).locked_by).to be_nil
943
+ expect(Delayed::Job.find(job3.id).locked_by).not_to be_nil
944
+ expect(Delayed::Job.find(job4.id).locked_by).not_to be_nil
852
945
 
853
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 0
946
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(0)
854
947
  end
855
948
  end
856
949
 
857
- it "should unlock orphaned jobs given a pid" do
950
+ it "unlocks orphaned jobs given a pid" do
858
951
  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')
952
+ job1 = Delayed::Job.new(tag: "tag")
953
+ job2 = Delayed::Job.new(tag: "tag")
954
+ job3 = Delayed::Job.new(tag: "tag")
955
+ job4 = Delayed::Job.new(tag: "tag")
863
956
  job1.create_and_lock!("Jobworker:#{Process.pid}")
864
957
  `echo ''`
865
958
  child_pid = $?.pid
@@ -869,15 +962,15 @@ shared_examples_for 'a backend' do
869
962
  job3.create_and_lock!("someoneelse:#{Process.pid}")
870
963
  job4.create_and_lock!("Jobworker:notanumber")
871
964
 
872
- Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker").should == 0
873
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 1
965
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker")).to eq(0)
966
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(1)
874
967
 
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
968
+ expect(Delayed::Job.find(job1.id).locked_by).not_to be_nil
969
+ expect(Delayed::Job.find(job2.id).locked_by).to be_nil
970
+ expect(Delayed::Job.find(job3.id).locked_by).not_to be_nil
971
+ expect(Delayed::Job.find(job4.id).locked_by).not_to be_nil
879
972
 
880
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 0
973
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(0)
881
974
  end
882
975
  end
883
976
  end