inst-jobs 2.3.1 → 2.4.1

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 +80 -69
  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 -192
  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 -17
  44. data/lib/delayed/work_queue/parent_process/client.rb +55 -53
  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 -261
  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 +16 -12
  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 +246 -0
  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 +537 -437
  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 +73 -52
  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,295 +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
- context 'singleton' do
317
- it "should create if there's no jobs on the strand" do
318
- @job = create_job(:singleton => 'myjobs')
319
- @job.should be_present
320
- Delayed::Job.get_and_lock_next_available('w1').should == @job
321
+ it "complains if you pass more than one strand-based option" do
322
+ expect { create_job(strand: "a", n_strand: "b") }.to raise_error(ArgumentError)
323
+ end
324
+
325
+ context "singleton" do
326
+ it "creates if there's no jobs on the strand" do
327
+ @job = create_job(singleton: "myjobs")
328
+ expect(@job).to be_present
329
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job)
321
330
  end
322
331
 
323
- it "should create if there's another job on the strand, but it's running" do
324
- @job = create_job(:singleton => 'myjobs')
325
- @job.should be_present
326
- Delayed::Job.get_and_lock_next_available('w1').should == @job
332
+ it "creates if there's another job on the strand, but it's running" do
333
+ @job = create_job(singleton: "myjobs")
334
+ expect(@job).to be_present
335
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job)
327
336
 
328
- @job2 = create_job(:singleton => 'myjobs')
329
- @job.should be_present
330
- @job2.should_not == @job
337
+ @job2 = create_job(singleton: "myjobs")
338
+ expect(@job).to be_present
339
+ expect(@job2).not_to eq(@job)
331
340
  end
332
341
 
333
- it "should not create if there's another non-running job on the strand" do
334
- @job = create_job(:singleton => 'myjobs')
335
- @job.should be_present
342
+ it "does not create if there's another non-running job on the strand" do
343
+ @job = create_job(singleton: "myjobs")
344
+ expect(@job).to be_present
336
345
 
337
- @job2 = create_job(:singleton => 'myjobs')
338
- @job2.should == @job
346
+ @job2 = create_job(singleton: "myjobs")
347
+ expect(@job2).to be_new_record
339
348
  end
340
349
 
341
- it "should not create if there's a job running and one waiting on the strand" do
342
- @job = create_job(:singleton => 'myjobs')
343
- @job.should be_present
344
- Delayed::Job.get_and_lock_next_available('w1').should == @job
350
+ it "does not create if there's a job running and one waiting on the strand" do
351
+ @job = create_job(singleton: "myjobs")
352
+ expect(@job).to be_present
353
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(@job)
345
354
 
346
- @job2 = create_job(:singleton => 'myjobs')
347
- @job2.should be_present
348
- @job2.should_not == @job
355
+ @job2 = create_job(singleton: "myjobs")
356
+ expect(@job2).to be_present
357
+ expect(@job2).not_to eq(@job)
349
358
 
350
- @job3 = create_job(:singleton => 'myjobs')
351
- @job3.should == @job2
359
+ @job3 = create_job(singleton: "myjobs")
360
+ expect(@job3).to be_new_record
352
361
  end
353
362
 
354
- it "should update existing job if new job is set to run sooner" do
355
- job1 = create_job(singleton: 'myjobs', run_at: 1.hour.from_now)
356
- job2 = create_job(singleton: 'myjobs')
357
- job2.should == job1
363
+ it "updates existing job if new job is set to run sooner" do
364
+ job1 = create_job(singleton: "myjobs", run_at: 1.hour.from_now)
365
+ job2 = create_job(singleton: "myjobs")
366
+ expect(job2).to eq(job1)
358
367
  # it should be scheduled to run immediately
359
- Delayed::Job.get_and_lock_next_available('w1').should == job1
368
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
360
369
  end
361
370
 
362
- it "should update existing job to a later date if requested" do
371
+ it "updates existing job to a later date if requested" do
363
372
  t1 = 1.hour.from_now
364
373
  t2 = 2.hours.from_now
365
- job1 = create_job(singleton: 'myjobs', run_at: t1)
366
- job2 = create_job(singleton: 'myjobs', run_at: t2)
367
- job2.should == job1
368
- job2.run_at.to_i.should == t1.to_i
369
-
370
- job3 = create_job(singleton: 'myjobs', run_at: t2, on_conflict: :overwrite)
371
- job3.should == job1
372
- job3.run_at.to_i.should == t2.to_i
374
+ job1 = create_job(singleton: "myjobs", run_at: t1)
375
+ job2 = create_job(singleton: "myjobs", run_at: t2)
376
+ expect(job2).to be_new_record
377
+
378
+ job3 = create_job(singleton: "myjobs", run_at: t2, on_conflict: :overwrite)
379
+ expect(job3).to eq(job1)
380
+ expect(job3.run_at.to_i).to eq(t2.to_i)
373
381
  end
374
382
 
375
- it "should update existing singleton job handler if requested" do
376
- job1 = Delayed::Job.enqueue(SimpleJob.new, queue: nil, singleton: 'myjobs', on_conflict: :overwrite)
377
- job2 = Delayed::Job.enqueue(ErrorJob.new, queue: nil, singleton: 'myjobs', on_conflict: :overwrite)
378
- job2.should == job1
379
- expect(job2.handler).to include("ErrorJob")
383
+ it "updates existing singleton job handler if requested" do
384
+ job1 = Delayed::Job.enqueue(SimpleJob.new, queue: nil, singleton: "myjobs", on_conflict: :overwrite)
385
+ job2 = Delayed::Job.enqueue(ErrorJob.new, queue: nil, singleton: "myjobs", on_conflict: :overwrite)
386
+ expect(job2).to eq(job1)
387
+ expect(job1.reload.handler).to include("ErrorJob")
380
388
  end
381
389
 
382
- it "does not create even if it's earlier when in loose mode" do
383
- t1 = 1.hour.from_now
384
- job1 = create_job(singleton: 'myjobs', run_at: t1)
385
- job2 = create_job(singleton: 'myjobs', on_conflict: :loose)
386
- job1.should == job2
387
- job2.run_at.to_i.should == t1.to_i
390
+ context "next_in_strand management" do
391
+ it "creates first as true, and second as false, then transitions to second when deleted" do
392
+ @job1 = create_job(singleton: "myjobs")
393
+ Delayed::Job.get_and_lock_next_available("w1")
394
+ @job2 = create_job(singleton: "myjobs")
395
+ expect(@job1.reload.next_in_strand).to eq true
396
+ expect(@job2.reload.next_in_strand).to eq false
397
+
398
+ @job1.destroy
399
+ expect(@job2.reload.next_in_strand).to eq true
400
+ end
401
+
402
+ it "when combined with a strand" do
403
+ job1 = create_job(singleton: "singleton", strand: "strand")
404
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job1
405
+ job2 = create_job(singleton: "singleton", strand: "strand")
406
+ expect(job2).not_to eq job1
407
+ expect(job2).not_to be_new_record
408
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
409
+ job3 = create_job(strand: "strand")
410
+ job4 = create_job(strand: "strand")
411
+ expect(job3.reload).not_to be_next_in_strand
412
+ expect(job4.reload).not_to be_next_in_strand
413
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
414
+ job1.destroy
415
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job2
416
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
417
+ job2.destroy
418
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job3
419
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
420
+ job3.destroy
421
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job4
422
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
423
+ end
424
+
425
+ it "when combined with a small n_strand" do
426
+ allow(Delayed::Settings).to receive(:num_strands).and_return(->(*) { 2 })
427
+
428
+ job1 = create_job(singleton: "singleton", n_strand: "strand")
429
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job1
430
+ job2 = create_job(singleton: "singleton", n_strand: "strand")
431
+ expect(job2).not_to eq job1
432
+ expect(job2).not_to be_new_record
433
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
434
+ job3 = create_job(n_strand: "strand")
435
+ job4 = create_job(n_strand: "strand")
436
+ expect(job3.reload).to be_next_in_strand
437
+ expect(job4.reload).not_to be_next_in_strand
438
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job3
439
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
440
+ # this doesn't unlock job2, even though it's ahead of job4
441
+ job3.destroy
442
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job4
443
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
444
+ job4.destroy
445
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
446
+ job1.destroy
447
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job2
448
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
449
+ end
450
+
451
+ it "when combined with a larger n_strand" do
452
+ allow(Delayed::Settings).to receive(:num_strands).and_return(->(*) { 10 })
453
+
454
+ job1 = create_job(singleton: "singleton", n_strand: "strand")
455
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job1
456
+ job2 = create_job(singleton: "singleton", n_strand: "strand")
457
+ expect(job2).not_to eq job1
458
+ expect(job2).not_to be_new_record
459
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
460
+ job3 = create_job(n_strand: "strand")
461
+ job4 = create_job(n_strand: "strand")
462
+ expect(job3.reload).to be_next_in_strand
463
+ expect(job4.reload).to be_next_in_strand
464
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job3
465
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job4
466
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
467
+ # this doesn't unlock job2
468
+ job3.destroy
469
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
470
+ job4.destroy
471
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
472
+ job1.destroy
473
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq job2
474
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
475
+ end
476
+ end
477
+
478
+ context "with on_conflict: loose and strand-inferred-from-singleton" do
479
+ around do |example|
480
+ Delayed::Settings.infer_strand_from_singleton = true
481
+ example.call
482
+ ensure
483
+ Delayed::Settings.infer_strand_from_singleton = false
484
+ end
485
+
486
+ it "does not create if there's another non-running job on the strand" do
487
+ @job = create_job(singleton: "myjobs", on_conflict: :loose)
488
+ expect(@job).to be_present
489
+
490
+ @job2 = create_job(singleton: "myjobs", on_conflict: :loose)
491
+ expect(@job2).to be_new_record
492
+ end
388
493
  end
389
494
  end
390
495
  end
391
496
 
392
497
  context "on hold" do
393
- it "should hold/unhold jobs" do
394
- job1 = create_job()
498
+ it "hold/unholds jobs" do
499
+ job1 = create_job
395
500
  job1.hold!
396
- Delayed::Job.get_and_lock_next_available('w1').should be_nil
501
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to be_nil
397
502
 
398
503
  job1.unhold!
399
- Delayed::Job.get_and_lock_next_available('w1').should == job1
504
+ expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
400
505
  end
401
506
  end
402
507
 
403
508
  context "periodic jobs" do
404
- before(:each) do
509
+ before do
405
510
  # make the periodic job get scheduled in the past
406
511
  @cron_time = 10.minutes.ago
407
512
  allow(Delayed::Periodic).to receive(:now).and_return(@cron_time)
408
513
  Delayed::Periodic.scheduled = {}
409
- Delayed::Periodic.cron('my SimpleJob', '*/5 * * * * *') do
514
+ Delayed::Periodic.cron("my SimpleJob", "*/5 * * * * *") do
410
515
  Delayed::Job.enqueue(SimpleJob.new)
411
516
  end
412
517
  end
413
518
 
414
- it "should schedule jobs if they aren't scheduled yet" do
415
- 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)
416
521
  Delayed::Periodic.perform_audit!
417
- Delayed::Job.jobs_count(:current).should == 1
418
- job = Delayed::Job.get_and_lock_next_available('test1')
419
- job.tag.should == 'periodic: my SimpleJob'
420
- job.payload_object.should == Delayed::Periodic.scheduled['my SimpleJob']
421
- job.run_at.should >= @cron_time
422
- job.run_at.should <= @cron_time + 6.minutes
423
- job.strand.should == job.tag
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)
424
529
  end
425
530
 
426
- it "should schedule jobs if there are only failed jobs on the queue" do
427
- 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)
428
533
  expect { Delayed::Periodic.perform_audit! }.to change { Delayed::Job.jobs_count(:current) }.by(1)
429
- Delayed::Job.jobs_count(:current).should == 1
430
- job = Delayed::Job.get_and_lock_next_available('test1')
534
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
535
+ job = Delayed::Job.get_and_lock_next_available("test1")
431
536
  job.fail!
432
- 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)
433
538
  end
434
539
 
435
- it "should not schedule jobs that are already scheduled" do
436
- 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)
437
542
  Delayed::Periodic.perform_audit!
438
- Delayed::Job.jobs_count(:current).should == 1
543
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
439
544
  job = Delayed::Job.find_available(1).first
440
545
  Delayed::Periodic.perform_audit!
441
- Delayed::Job.jobs_count(:current).should == 1
546
+ expect(Delayed::Job.jobs_count(:current)).to eq(1)
442
547
  # verify that the same job still exists, it wasn't just replaced with a new one
443
- job.should == Delayed::Job.find_available(1).first
548
+ expect(job).to eq(Delayed::Job.find_available(1).first)
444
549
  end
445
550
 
446
- it "should schedule the next job run after performing" do
447
- 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)
448
553
  Delayed::Periodic.perform_audit!
449
- Delayed::Job.jobs_count(:current).should == 1
450
- 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")
451
556
  run_job(job)
452
557
 
453
- job = Delayed::Job.get_and_lock_next_available('test1')
454
- job.tag.should == 'SimpleJob#perform'
558
+ job = Delayed::Job.get_and_lock_next_available("test1")
559
+ expect(job.tag).to eq("SimpleJob#perform")
455
560
 
456
- next_scheduled = Delayed::Job.get_and_lock_next_available('test2')
457
- next_scheduled.tag.should == 'periodic: my SimpleJob'
458
- next_scheduled.payload_object.should be_is_a(Delayed::Periodic)
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)
459
564
  end
460
565
 
461
- it "should reject duplicate named jobs" do
462
- 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)
463
568
  end
464
569
 
465
- it "should handle jobs that are no longer scheduled" do
570
+ it "handles jobs that are no longer scheduled" do
466
571
  Delayed::Periodic.perform_audit!
467
572
  Delayed::Periodic.scheduled = {}
468
- job = Delayed::Job.get_and_lock_next_available('test')
573
+ job = Delayed::Job.get_and_lock_next_available("test")
469
574
  run_job(job)
470
575
  # shouldn't error, and the job should now be deleted
471
- Delayed::Job.jobs_count(:current).should == 0
576
+ expect(Delayed::Job.jobs_count(:current)).to eq(0)
472
577
  end
473
578
 
474
- it "should allow overriding schedules using periodic_jobs.yml" do
475
- 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
476
581
  Delayed::Periodic.scheduled = {}
477
- Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
582
+ Delayed::Periodic.cron("my ChangedJob", "*/5 * * * * *") do
478
583
  Delayed::Job.enqueue(SimpleJob.new)
479
584
  end
480
- Delayed::Periodic.scheduled['my ChangedJob'].cron.original.should == '*/10 * * * * *'
585
+ expect(Delayed::Periodic.scheduled["my ChangedJob"].cron.original).to eq("*/10 * * * * *")
481
586
  end
482
587
  end
483
588
 
484
- it "should fail if the override cron line is invalid" do
485
- 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
486
591
  Delayed::Periodic.scheduled = {}
487
- expect { Delayed::Periodic.cron('my ChangedJob', '*/5 * * * * *') do
488
- Delayed::Job.enqueue(SimpleJob.new)
489
- 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)
490
597
  end
491
598
 
492
- 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)
493
602
  end
494
603
  end
495
604
 
496
- module InDelayedJobTest
497
- def self.check_in_job
498
- Delayed::Job.in_delayed_job?.should == true
499
- end
500
- end
501
-
502
- it "should set in_delayed_job?" do
605
+ it "sets in_delayed_job?" do
503
606
  job = InDelayedJobTest.delay(ignore_transaction: true).check_in_job
504
- Delayed::Job.in_delayed_job?.should == false
607
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
505
608
  job.invoke_job
506
- Delayed::Job.in_delayed_job?.should == false
609
+ expect(Delayed::Job.in_delayed_job?).to eq(false)
507
610
  end
508
611
 
509
- it "should fail on job creation if an unsaved AR object is used" do
510
- story = Story.new :text => "Once upon..."
511
- lambda { story.delay.text }.should raise_error(RuntimeError)
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)
512
615
 
513
616
  reader = StoryReader.new
514
- lambda { reader.delay.read(story) }.should raise_error(RuntimeError)
617
+ expect { reader.delay.read(story) }.to raise_error(RuntimeError)
515
618
 
516
- lambda { [story, 1, story, false].delay.first }.should raise_error(RuntimeError)
619
+ expect { [story, 1, story, false].delay.first }.to raise_error(RuntimeError)
517
620
  end
518
621
 
519
622
  # the sort order of current_jobs and list_jobs depends on the back-end
@@ -521,62 +624,62 @@ shared_examples_for 'a backend' do
521
624
  describe "current jobs, queue size, strand_size" do
522
625
  before do
523
626
  @jobs = []
524
- 3.times { @jobs << create_job(:priority => 3) }
525
- @jobs.unshift create_job(:priority => 2)
526
- @jobs.unshift create_job(:priority => 1)
527
- @jobs << create_job(:priority => 3, :strand => "test1")
528
- @future_job = create_job(:run_at => 5.hours.from_now)
529
- 2.times { @jobs << create_job(:priority => 3) }
530
- @jobs << create_job(:priority => 3, :strand => "test1")
531
- @failed_job = create_job.tap { |j| j.fail! }
532
- @other_queue_job = create_job(:queue => "another")
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")
533
636
  end
534
637
 
535
- it "should return the queued jobs" do
536
- 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)
537
640
  end
538
641
 
539
- it "should paginate the returned jobs" do
642
+ it "paginates the returned jobs" do
540
643
  @returned = []
541
644
  @returned += Delayed::Job.list_jobs(:current, 3, 0)
542
645
  @returned += Delayed::Job.list_jobs(:current, 4, 3)
543
646
  @returned += Delayed::Job.list_jobs(:current, 100, 7)
544
- @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))
545
648
  end
546
649
 
547
- it "should return other queues" do
548
- 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])
549
652
  end
550
653
 
551
- it "should return queue size" do
552
- Delayed::Job.jobs_count(:current).should == @jobs.size
553
- Delayed::Job.jobs_count(:current, "another").should == 1
554
- Delayed::Job.jobs_count(:current, "bogus").should == 0
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)
555
658
  end
556
659
 
557
- it "should return strand size" do
558
- Delayed::Job.strand_size("test1").should == 2
559
- 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)
560
663
  end
561
664
  end
562
665
 
563
- it "should return the jobs in a strand" do
666
+ it "returns the jobs in a strand" do
564
667
  strand_jobs = []
565
- 3.times { strand_jobs << create_job(:strand => 'test1') }
566
- 2.times { create_job(:strand => 'test2') }
567
- strand_jobs << create_job(:strand => 'test1', :run_at => 5.hours.from_now)
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)
568
671
  create_job
569
672
 
570
673
  jobs = Delayed::Job.list_jobs(:strand, 3, 0, "test1")
571
- jobs.size.should == 3
674
+ expect(jobs.size).to eq(3)
572
675
 
573
676
  jobs += Delayed::Job.list_jobs(:strand, 3, 3, "test1")
574
- jobs.size.should == 4
677
+ expect(jobs.size).to eq(4)
575
678
 
576
- 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))
577
680
  end
578
681
 
579
- it "should return the jobs for a tag" do
682
+ it "returns the jobs for a tag" do
580
683
  tag_jobs = []
581
684
  3.times { tag_jobs << "test".delay(ignore_transaction: true).to_s }
582
685
  2.times { "test".delay.to_i }
@@ -586,62 +689,62 @@ shared_examples_for 'a backend' do
586
689
  create_job
587
690
 
588
691
  jobs = Delayed::Job.list_jobs(:tag, 3, 0, "String#to_s")
589
- jobs.size.should == 3
692
+ expect(jobs.size).to eq(3)
590
693
 
591
694
  jobs += Delayed::Job.list_jobs(:tag, 3, 3, "String#to_s")
592
- jobs.size.should == 5
695
+ expect(jobs.size).to eq(5)
593
696
 
594
- 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))
595
698
  end
596
699
 
597
700
  describe "running_jobs" do
598
- it "should return the running jobs, ordered by locked_at" do
701
+ it "returns the running jobs, ordered by locked_at" do
599
702
  Timecop.freeze(10.minutes.ago) { 3.times { create_job } }
600
- j1 = Timecop.freeze(2.minutes.ago) { Delayed::Job.get_and_lock_next_available('w1') }
601
- j2 = Timecop.freeze(5.minutes.ago) { Delayed::Job.get_and_lock_next_available('w2') }
602
- j3 = Timecop.freeze(5.seconds.ago) { Delayed::Job.get_and_lock_next_available('w3') }
603
- [j1, j2, j3].compact.size.should == 3
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)
604
707
 
605
- Delayed::Job.running_jobs.should == [j2, j1, j3]
708
+ expect(Delayed::Job.running_jobs).to eq([j2, j1, j3])
606
709
  end
607
710
  end
608
711
 
609
712
  describe "future jobs" do
610
- it "should find future jobs once their run_at rolls by" do
611
- Timecop.freeze {
612
- @job = create_job :run_at => 5.minutes.from_now
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
613
716
  expect(Delayed::Job.find_available(5)).not_to include(@job)
614
- }
615
- Timecop.freeze(1.hour.from_now) {
717
+ end
718
+ Timecop.freeze(1.hour.from_now) do
616
719
  expect(Delayed::Job.find_available(5)).to include(@job)
617
- Delayed::Job.get_and_lock_next_available('test').should == @job
618
- }
720
+ expect(Delayed::Job.get_and_lock_next_available("test")).to eq(@job)
721
+ end
619
722
  end
620
723
 
621
- it "should return future jobs sorted by their run_at" do
724
+ it "returns future jobs sorted by their run_at" do
622
725
  @j1 = create_job
623
- @j2 = create_job :run_at => 1.hour.from_now
624
- @j3 = create_job :run_at => 30.minutes.from_now
625
- Delayed::Job.list_jobs(:future, 1).should == [@j3]
626
- Delayed::Job.list_jobs(:future, 5).should == [@j3, @j2]
627
- Delayed::Job.list_jobs(:future, 1, 1).should == [@j2]
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])
628
731
  end
629
732
  end
630
733
 
631
734
  describe "failed jobs" do
632
735
  # the sort order of failed_jobs depends on the back-end implementation,
633
736
  # so sort order isn't tested here
634
- it "should return the list of failed jobs" do
737
+ it "returns the list of failed jobs" do
635
738
  jobs = []
636
- 3.times { jobs << create_job(:priority => 3) }
637
- jobs = jobs.sort_by { |j| j.id }
638
- Delayed::Job.list_jobs(:failed, 1).should == []
739
+ 3.times { jobs << create_job(priority: 3) }
740
+ jobs = jobs.sort_by(&:id)
741
+ expect(Delayed::Job.list_jobs(:failed, 1)).to eq([])
639
742
  jobs[0].fail!
640
743
  jobs[1].fail!
641
- failed = (Delayed::Job.list_jobs(:failed, 1, 0) + Delayed::Job.list_jobs(:failed, 1, 1)).sort_by { |j| j.id }
642
- failed.size.should == 2
643
- failed[0].original_job_id.should == jobs[0].id
644
- failed[1].original_job_id.should == jobs[1].id
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)
645
748
  end
646
749
  end
647
750
 
@@ -652,126 +755,123 @@ shared_examples_for 'a backend' do
652
755
  @ignored_jobs = []
653
756
  end
654
757
 
655
- it "should hold and unhold a scope of jobs" do
656
- @affected_jobs.all? { |j| j.on_hold? }.should be false
657
- @ignored_jobs.any? { |j| j.on_hold? }.should be false
658
- Delayed::Job.bulk_update('hold', :flavor => @flavor, :query => @query).should == @affected_jobs.size
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)
659
762
 
660
- @affected_jobs.all? { |j| Delayed::Job.find(j.id).on_hold? }.should be true
661
- @ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
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
662
765
 
663
- # redis holding seems busted - it removes from the tag set and strand list, so you can't use a query
664
- # to un-hold them
665
- next if Delayed::Job == Delayed::Backend::Redis::Job
666
- Delayed::Job.bulk_update('unhold', :flavor => @flavor, :query => @query).should == @affected_jobs.size
766
+ expect(Delayed::Job.bulk_update("unhold", flavor: @flavor, query: @query)).to eq(@affected_jobs.size)
667
767
 
668
- @affected_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
669
- @ignored_jobs.any? { |j| Delayed::Job.find(j.id).on_hold? }.should be false
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
670
770
  end
671
771
 
672
- it "should delete a scope of jobs" do
673
- Delayed::Job.bulk_update('destroy', :flavor => @flavor, :query => @query).should == @affected_jobs.size
674
- @affected_jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.should be_blank
675
- @ignored_jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.size.should == @ignored_jobs.size
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
676
776
  end
677
777
  end
678
778
 
679
779
  describe "scope: current" do
680
780
  include_examples "scope"
681
- before do
682
- @flavor = 'current'
781
+ before do # rubocop:disable RSpec/HooksBeforeExamples
782
+ @flavor = "current"
683
783
  Timecop.freeze(5.minutes.ago) do
684
784
  3.times { @affected_jobs << create_job }
685
- @ignored_jobs << create_job(:run_at => 2.hours.from_now)
686
- @ignored_jobs << create_job(:queue => 'q2')
785
+ @ignored_jobs << create_job(run_at: 2.hours.from_now)
786
+ @ignored_jobs << create_job(queue: "q2")
687
787
  end
688
788
  end
689
789
  end
690
790
 
691
791
  describe "scope: future" do
692
792
  include_examples "scope"
693
- before do
694
- @flavor = 'future'
793
+ before do # rubocop:disable RSpec/HooksBeforeExamples
794
+ @flavor = "future"
695
795
  Timecop.freeze(5.minutes.ago) do
696
- 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) }
697
797
  @ignored_jobs << create_job
698
- @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)
699
799
  end
700
800
  end
701
801
  end
702
802
 
703
803
  describe "scope: strand" do
704
804
  include_examples "scope"
705
- before do
706
- @flavor = 'strand'
707
- @query = 's1'
805
+ before do # rubocop:disable RSpec/HooksBeforeExamples
806
+ @flavor = "strand"
807
+ @query = "s1"
708
808
  Timecop.freeze(5.minutes.ago) do
709
- @affected_jobs << create_job(:strand => 's1')
710
- @affected_jobs << create_job(:strand => 's1', :run_at => 2.hours.from_now)
809
+ @affected_jobs << create_job(strand: "s1")
810
+ @affected_jobs << create_job(strand: "s1", run_at: 2.hours.from_now)
711
811
  @ignored_jobs << create_job
712
- @ignored_jobs << create_job(:strand => 's2')
713
- @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)
714
814
  end
715
815
  end
716
816
  end
717
817
 
718
818
  describe "scope: tag" do
719
819
  include_examples "scope"
720
- before do
721
- @flavor = 'tag'
722
- @query = 'String#to_i'
820
+ before do # rubocop:disable RSpec/HooksBeforeExamples
821
+ @flavor = "tag"
822
+ @query = "String#to_i"
723
823
  Timecop.freeze(5.minutes.ago) do
724
824
  @affected_jobs << "test".delay(ignore_transaction: true).to_i
725
- @affected_jobs << "test".delay(strand: 's1', ignore_transaction: true).to_i
825
+ @affected_jobs << "test".delay(strand: "s1", ignore_transaction: true).to_i
726
826
  @affected_jobs << "test".delay(run_at: 2.hours.from_now, ignore_transaction: true).to_i
727
827
  @ignored_jobs << create_job
728
- @ignored_jobs << create_job(:run_at => 1.hour.from_now)
828
+ @ignored_jobs << create_job(run_at: 1.hour.from_now)
729
829
  end
730
830
  end
731
831
  end
732
832
 
733
- it "should hold and un-hold given job ids" do
833
+ it "holds and un-hold given job ids" do
734
834
  j1 = "test".delay(ignore_transaction: true).to_i
735
- j2 = create_job(:run_at => 2.hours.from_now)
736
- j3 = "test".delay(strand: 's1', ignore_transaction: true).to_i
737
- Delayed::Job.bulk_update('hold', :ids => [j1.id, j2.id]).should == 2
738
- Delayed::Job.find(j1.id).on_hold?.should be true
739
- Delayed::Job.find(j2.id).on_hold?.should be true
740
- Delayed::Job.find(j3.id).on_hold?.should be false
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
741
841
 
742
- Delayed::Job.bulk_update('unhold', :ids => [j2.id, j3.id]).should == 1
743
- Delayed::Job.find(j1.id).on_hold?.should be true
744
- Delayed::Job.find(j2.id).on_hold?.should be false
745
- Delayed::Job.find(j3.id).on_hold?.should be false
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
746
846
  end
747
847
 
748
- it "should not hold locked jobs" do
749
- job1 = Delayed::Job.new(:tag => 'tag')
848
+ it "does not hold locked jobs" do
849
+ job1 = Delayed::Job.new(tag: "tag")
750
850
  job1.create_and_lock!("worker")
751
- job1.on_hold?.should be false
752
- Delayed::Job.bulk_update('hold', ids: [job1.id]).should == 0
753
- Delayed::Job.find(job1.id).on_hold?.should be false
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
754
854
  end
755
855
 
756
- it "should not unhold locked jobs" do
757
- job1 = Delayed::Job.new(:tag => 'tag')
856
+ it "does not unhold locked jobs" do
857
+ job1 = Delayed::Job.new(tag: "tag")
758
858
  job1.create_and_lock!("worker")
759
- Delayed::Job.bulk_update('unhold', ids: [job1.id]).should == 0
760
- Delayed::Job.find(job1.id).on_hold?.should be false
761
- Delayed::Job.find(job1.id).locked?.should be true
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
762
862
  end
763
863
 
764
- it "should delete given job ids" do
864
+ it "deletes given job ids" do
765
865
  jobs = (0..2).map { create_job }
766
- Delayed::Job.bulk_update('destroy', :ids => jobs[0,2].map(&:id)).should == 2
767
- jobs.map { |j| Delayed::Job.find(j.id) rescue nil }.compact.should == jobs[2,1]
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]
768
868
  end
769
869
 
770
- it "should not delete locked jobs" do
771
- job1 = Delayed::Job.new(:tag => 'tag')
870
+ it "does not delete locked jobs" do
871
+ job1 = Delayed::Job.new(tag: "tag")
772
872
  job1.create_and_lock!("worker")
773
- Delayed::Job.bulk_update('destroy', ids: [job1.id]).should == 0
774
- Delayed::Job.find(job1.id).locked?.should be true
873
+ expect(Delayed::Job.bulk_update("destroy", ids: [job1.id])).to eq(0)
874
+ expect(Delayed::Job.find(job1.id).locked?).to be true
775
875
  end
776
876
  end
777
877
 
@@ -779,7 +879,7 @@ shared_examples_for 'a backend' do
779
879
  before do
780
880
  @cur = []
781
881
  3.times { @cur << "test".delay(ignore_transaction: true).to_s }
782
- 5.times { @cur << "test".delay(ignore_transaction: true).to_i}
882
+ 5.times { @cur << "test".delay(ignore_transaction: true).to_i }
783
883
  2.times { @cur << "test".delay(ignore_transaction: true).upcase }
784
884
  "test".delay(ignore_transaction: true).downcase.fail!
785
885
  @future = []
@@ -787,48 +887,48 @@ shared_examples_for 'a backend' do
787
887
  @cur << "test".delay(ignore_transaction: true).downcase
788
888
  end
789
889
 
790
- it "should return a sorted list of popular current tags" do
791
- Delayed::Job.tag_counts(:current, 1).should == [{ :tag => "String#to_i", :count => 5 }]
792
- Delayed::Job.tag_counts(:current, 1, 1).should == [{ :tag => "String#to_s", :count => 3 }]
793
- Delayed::Job.tag_counts(:current, 5).should == [{ :tag => "String#to_i", :count => 5 },
794
- { :tag => "String#to_s", :count => 3 },
795
- { :tag => "String#upcase", :count => 2 },
796
- { :tag => "String#downcase", :count => 1 }]
797
- @cur[0,4].each { |j| j.destroy }
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)
798
898
  @future[0].run_at = @future[1].run_at = 1.hour.ago
799
899
  @future[0].save!
800
900
  @future[1].save!
801
901
 
802
- Delayed::Job.tag_counts(:current, 5).should == [{ :tag => "String#to_i", :count => 4 },
803
- { :tag => "String#downcase", :count => 3 },
804
- { :tag => "String#upcase", :count => 2 },]
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 }])
805
905
  end
806
906
 
807
- it "should return a sorted list of all popular tags" do
808
- Delayed::Job.tag_counts(:all, 1).should == [{ :tag => "String#downcase", :count => 6 }]
809
- Delayed::Job.tag_counts(:all, 1, 1).should == [{ :tag => "String#to_i", :count => 5 }]
810
- Delayed::Job.tag_counts(:all, 5).should == [{ :tag => "String#downcase", :count => 6 },
811
- { :tag => "String#to_i", :count => 5 },
812
- { :tag => "String#to_s", :count => 3 },
813
- { :tag => "String#upcase", :count => 2 },]
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 }])
814
914
 
815
- @cur[0,4].each { |j| j.destroy }
915
+ @cur[0, 4].each(&:destroy)
816
916
  @future[0].destroy
817
917
  @future[1].fail!
818
918
  @future[2].fail!
819
919
 
820
- Delayed::Job.tag_counts(:all, 5).should == [{ :tag => "String#to_i", :count => 4 },
821
- { :tag => "String#downcase", :count => 3 },
822
- { :tag => "String#upcase", :count => 2 },]
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 }])
823
923
  end
824
924
  end
825
925
 
826
- it "should unlock orphaned jobs" do
926
+ it "unlocks orphaned jobs" do
827
927
  change_setting(Delayed::Settings, :max_attempts, 2) do
828
- job1 = Delayed::Job.new(:tag => 'tag')
829
- job2 = Delayed::Job.new(:tag => 'tag')
830
- job3 = Delayed::Job.new(:tag => 'tag')
831
- job4 = Delayed::Job.new(:tag => 'tag')
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")
832
932
  job1.create_and_lock!("Jobworker:#{Process.pid}")
833
933
  `echo ''`
834
934
  child_pid = $?.pid
@@ -836,23 +936,23 @@ shared_examples_for 'a backend' do
836
936
  job3.create_and_lock!("someoneelse:#{Process.pid}")
837
937
  job4.create_and_lock!("Jobworker:notanumber")
838
938
 
839
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 1
939
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(1)
840
940
 
841
- Delayed::Job.find(job1.id).locked_by.should_not be_nil
842
- Delayed::Job.find(job2.id).locked_by.should be_nil
843
- Delayed::Job.find(job3.id).locked_by.should_not be_nil
844
- Delayed::Job.find(job4.id).locked_by.should_not be_nil
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
845
945
 
846
- Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker").should == 0
946
+ expect(Delayed::Job.unlock_orphaned_jobs(nil, "Jobworker")).to eq(0)
847
947
  end
848
948
  end
849
949
 
850
- it "should unlock orphaned jobs given a pid" do
950
+ it "unlocks orphaned jobs given a pid" do
851
951
  change_setting(Delayed::Settings, :max_attempts, 2) do
852
- job1 = Delayed::Job.new(:tag => 'tag')
853
- job2 = Delayed::Job.new(:tag => 'tag')
854
- job3 = Delayed::Job.new(:tag => 'tag')
855
- job4 = Delayed::Job.new(:tag => 'tag')
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")
856
956
  job1.create_and_lock!("Jobworker:#{Process.pid}")
857
957
  `echo ''`
858
958
  child_pid = $?.pid
@@ -862,15 +962,15 @@ shared_examples_for 'a backend' do
862
962
  job3.create_and_lock!("someoneelse:#{Process.pid}")
863
963
  job4.create_and_lock!("Jobworker:notanumber")
864
964
 
865
- Delayed::Job.unlock_orphaned_jobs(child_pid2, "Jobworker").should == 0
866
- 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)
867
967
 
868
- Delayed::Job.find(job1.id).locked_by.should_not be_nil
869
- Delayed::Job.find(job2.id).locked_by.should be_nil
870
- Delayed::Job.find(job3.id).locked_by.should_not be_nil
871
- Delayed::Job.find(job4.id).locked_by.should_not be_nil
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
872
972
 
873
- Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker").should == 0
973
+ expect(Delayed::Job.unlock_orphaned_jobs(child_pid, "Jobworker")).to eq(0)
874
974
  end
875
975
  end
876
976
  end