que 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +21 -1
  5. data/Gemfile +5 -0
  6. data/README.md +7 -6
  7. data/docs/advanced_setup.md +14 -4
  8. data/docs/customizing_que.md +4 -4
  9. data/docs/error_handling.md +13 -1
  10. data/docs/managing_workers.md +2 -2
  11. data/docs/migrating.md +26 -0
  12. data/docs/multiple_queues.md +13 -0
  13. data/docs/shutting_down_safely.md +7 -0
  14. data/docs/writing_reliable_jobs.md +43 -0
  15. data/lib/generators/que/templates/add_que.rb +1 -1
  16. data/lib/que.rb +27 -41
  17. data/lib/que/adapters/base.rb +75 -4
  18. data/lib/que/job.rb +45 -28
  19. data/lib/que/migrations.rb +3 -2
  20. data/lib/que/migrations/{1-down.sql → 1/down.sql} +0 -0
  21. data/lib/que/migrations/{1-up.sql → 1/up.sql} +0 -0
  22. data/lib/que/migrations/{2-down.sql → 2/down.sql} +0 -0
  23. data/lib/que/migrations/{2-up.sql → 2/up.sql} +0 -0
  24. data/lib/que/migrations/3/down.sql +5 -0
  25. data/lib/que/migrations/3/up.sql +5 -0
  26. data/lib/que/sql.rb +24 -17
  27. data/lib/que/version.rb +1 -1
  28. data/lib/que/worker.rb +6 -5
  29. data/spec/adapters/active_record_spec.rb +6 -6
  30. data/spec/adapters/sequel_spec.rb +4 -4
  31. data/spec/gemfiles/Gemfile1 +18 -0
  32. data/spec/gemfiles/Gemfile2 +18 -0
  33. data/spec/support/helpers.rb +2 -1
  34. data/spec/support/shared_examples/adapter.rb +7 -3
  35. data/spec/support/shared_examples/multi_threaded_adapter.rb +2 -2
  36. data/spec/travis.rb +12 -4
  37. data/spec/unit/customization_spec.rb +148 -0
  38. data/spec/unit/{queue_spec.rb → enqueue_spec.rb} +115 -14
  39. data/spec/unit/logging_spec.rb +3 -2
  40. data/spec/unit/migrations_spec.rb +3 -2
  41. data/spec/unit/pool_spec.rb +30 -6
  42. data/spec/unit/run_spec.rb +12 -0
  43. data/spec/unit/states_spec.rb +29 -31
  44. data/spec/unit/stats_spec.rb +16 -14
  45. data/spec/unit/work_spec.rb +120 -25
  46. data/spec/unit/worker_spec.rb +55 -9
  47. data/tasks/safe_shutdown.rb +1 -1
  48. metadata +30 -17
@@ -1,12 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Logging" do
4
- it "by default should record the library and thread id in JSON" do
4
+ it "by default should record the library and hostname and thread id in JSON" do
5
5
  Que.log :event => "blah", :source => 4
6
6
  $logger.messages.count.should be 1
7
7
 
8
8
  message = JSON.load($logger.messages.first)
9
9
  message['lib'].should == 'que'
10
+ message['hostname'].should == Socket.gethostname
10
11
  message['event'].should == 'blah'
11
12
  message['source'].should == 4
12
13
  message['thread'].should == Thread.current.object_id
@@ -16,7 +17,7 @@ describe "Logging" do
16
17
  begin
17
18
  Que.logger = nil
18
19
 
19
- Que::Job.queue
20
+ Que::Job.enqueue
20
21
  worker = Que::Worker.new
21
22
  sleep_until { worker.sleeping? }
22
23
 
@@ -7,7 +7,7 @@ describe Que::Migrations do
7
7
 
8
8
  default = proc do
9
9
  result = Que.execute <<-SQL
10
- select adsrc
10
+ select adsrc::integer
11
11
  from pg_attribute a
12
12
  join pg_class c on c.oid = a.attrelid
13
13
  join pg_attrdef on adrelid = attrelid AND adnum = attnum
@@ -15,7 +15,7 @@ describe Que::Migrations do
15
15
  and attname = 'priority'
16
16
  SQL
17
17
 
18
- result.first['adsrc'].to_i
18
+ result.first[:adsrc]
19
19
  end
20
20
 
21
21
  default.call.should == 100
@@ -40,6 +40,7 @@ describe Que::Migrations do
40
40
  Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
41
41
  Que::Migrations.migrate! :version => 0
42
42
  Que::Migrations.db_version.should == 0
43
+ Que.db_version.should == 0
43
44
  Que::Migrations.migrate!
44
45
  Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
45
46
 
@@ -19,15 +19,15 @@ describe "Managing the Worker pool" do
19
19
  it "should make jobs run in the same thread as they are queued" do
20
20
  Que.mode = :sync
21
21
 
22
- ArgsJob.queue(5, :testing => "synchronous").should be_an_instance_of ArgsJob
23
- $passed_args.should == [5, {'testing' => "synchronous"}]
22
+ ArgsJob.enqueue(5, :testing => "synchronous").should be_an_instance_of ArgsJob
23
+ $passed_args.should == [5, {:testing => "synchronous"}]
24
24
  DB[:que_jobs].count.should be 0
25
25
  end
26
26
 
27
27
  it "should not affect jobs that are queued with specific run_ats" do
28
28
  Que.mode = :sync
29
29
 
30
- ArgsJob.queue(5, :testing => "synchronous", :run_at => Time.now + 60)
30
+ ArgsJob.enqueue(5, :testing => "synchronous", :run_at => Time.now + 60)
31
31
  DB[:que_jobs].select_map(:job_class).should == ["ArgsJob"]
32
32
  end
33
33
  end
@@ -132,7 +132,7 @@ describe "Managing the Worker pool" do
132
132
  Que.mode = :async
133
133
  sleep_until { Que::Worker.workers.all? &:sleeping? }
134
134
 
135
- BlockJob.queue
135
+ BlockJob.enqueue
136
136
  Que.wake!
137
137
 
138
138
  $q1.pop
@@ -158,7 +158,7 @@ describe "Managing the Worker pool" do
158
158
  Que.mode = :async
159
159
  sleep_until { Que::Worker.workers.all? &:sleeping? }
160
160
 
161
- 4.times { BlockJob.queue }
161
+ 4.times { BlockJob.enqueue }
162
162
  Que.wake_all!
163
163
  4.times { $q1.pop }
164
164
 
@@ -179,8 +179,32 @@ describe "Managing the Worker pool" do
179
179
  Que.mode = :async
180
180
  sleep_until { Que::Worker.workers.all? &:sleeping? }
181
181
  Que.wake_interval = 0.01 # 10 ms
182
- Que::Job.queue
182
+ Que::Job.enqueue
183
183
  sleep_until { DB[:que_jobs].count == 0 }
184
184
  end
185
+
186
+ it "should work jobs in the queue defined by QUE_QUEUE" do
187
+ begin
188
+ Que::Job.enqueue 1
189
+ Que::Job.enqueue 2, :queue => 'my_queue'
190
+
191
+ ENV['QUE_QUEUE'] = 'my_queue'
192
+
193
+ Que.mode = :async
194
+ sleep_until { Que::Worker.workers.all? &:sleeping? }
195
+ DB[:que_jobs].count.should be 1
196
+
197
+ job = DB[:que_jobs].first
198
+ job[:queue].should == ''
199
+ job[:args].should == '[1]'
200
+ ensure
201
+ ENV.delete('QUE_QUEUE')
202
+
203
+ if @worker
204
+ @worker.stop
205
+ @worker.wait_until_stopped
206
+ end
207
+ end
208
+ end
185
209
  end
186
210
  end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Que::Job, '.run' do
4
+ it "should immediately process the job with the arguments given to it" do
5
+ result = ArgsJob.run 1, 'two', {:three => 3}
6
+ result.should be_an_instance_of ArgsJob
7
+ result.attrs[:args].should == [1, 'two', {:three => 3}]
8
+
9
+ DB[:que_jobs].count.should be 0
10
+ $passed_args.should == [1, 'two', {:three => 3}]
11
+ end
12
+ end
@@ -6,45 +6,43 @@ describe Que, '.worker_states' do
6
6
 
7
7
  class WorkerStateJob < BlockJob
8
8
  def run
9
- $pid = Que.execute("select pg_backend_pid()").first['pg_backend_pid']
9
+ $pid = Que.execute("select pg_backend_pid()").first[:pg_backend_pid]
10
10
  super
11
11
  end
12
12
  end
13
13
 
14
- WorkerStateJob.queue :priority => 2
14
+ WorkerStateJob.enqueue :priority => 2
15
15
 
16
16
  # Ensure that the portion of the SQL query that accounts for bigint
17
17
  # job_ids functions correctly.
18
18
  DB[:que_jobs].update(:job_id => 2**33)
19
19
 
20
- begin
21
- t = Thread.new { Que::Job.work }
22
- $q1.pop
23
-
24
- states = Que.worker_states
25
- states.length.should be 1
26
-
27
- $q2.push nil
28
- t.join
29
-
30
- state = states.first
31
- state.keys.should == %w(priority run_at job_id job_class args error_count last_error pg_backend_pid pg_state pg_state_changed_at pg_last_query pg_last_query_started_at pg_transaction_started_at pg_waiting_on_lock)
32
-
33
- state[:priority].should == '2'
34
- Time.parse(state[:run_at]).should be_within(3).of Time.now
35
- state[:job_id].should == (2**33).to_s
36
- state[:job_class].should == 'WorkerStateJob'
37
- state[:args].should == '[]'
38
- state[:error_count].should == '0'
39
- state[:last_error].should be nil
40
-
41
- state[:pg_backend_pid].should == $pid.to_s
42
- state[:pg_state].should == 'idle'
43
- Time.parse(state[:pg_state_changed_at]).should be_within(3).of Time.now
44
- state[:pg_last_query].should == 'select pg_backend_pid()'
45
- Time.parse(state[:pg_last_query_started_at]).should be_within(3).of Time.now
46
- state[:pg_transaction_started_at].should == nil
47
- state[:pg_waiting_on_lock].should == 'f'
48
- end
20
+ t = Thread.new { Que::Job.work }
21
+ $q1.pop
22
+
23
+ states = Que.worker_states
24
+ states.length.should be 1
25
+
26
+ $q2.push nil
27
+ t.join
28
+
29
+ state = states.first
30
+ state.keys.should == %w(priority run_at job_id job_class args error_count last_error queue pg_backend_pid pg_state pg_state_changed_at pg_last_query pg_last_query_started_at pg_transaction_started_at pg_waiting_on_lock)
31
+
32
+ state[:priority].should == 2
33
+ state[:run_at].should be_within(3).of Time.now
34
+ state[:job_id].should == 2**33
35
+ state[:job_class].should == 'WorkerStateJob'
36
+ state[:args].should == []
37
+ state[:error_count].should == 0
38
+ state[:last_error].should be nil
39
+
40
+ state[:pg_backend_pid].should == $pid
41
+ state[:pg_state].should == 'idle'
42
+ state[:pg_state_changed_at].should be_within(3).of Time.now
43
+ state[:pg_last_query].should == 'select pg_backend_pid()'
44
+ state[:pg_last_query_started_at].should be_within(3).of Time.now
45
+ state[:pg_transaction_started_at].should == nil
46
+ state[:pg_waiting_on_lock].should == false
49
47
  end if QUE_ADAPTERS[:connection_pool]
50
48
  end
@@ -2,15 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  describe Que, '.job_stats' do
4
4
  it "should return a list of the job types in the queue, their counts and the number of each currently running" do
5
- BlockJob.queue
6
- Que::Job.queue
5
+ BlockJob.enqueue
6
+ Que::Job.enqueue
7
7
 
8
8
  # Have to tweak the job_id to ensure that the portion of the SQL query
9
9
  # that accounts for bigint job_ids functions correctly.
10
10
  old = Time.now - 3600
11
11
  DB[:que_jobs].where(:job_class => "Que::Job").update(:job_id => 2**33, :error_count => 5, :run_at => old)
12
12
 
13
- Que::Job.queue
13
+ Que::Job.enqueue
14
14
 
15
15
  begin
16
16
  DB.get{pg_advisory_lock(2**33)}
@@ -20,21 +20,23 @@ describe Que, '.job_stats' do
20
20
 
21
21
  qj, bj = stats
22
22
 
23
- qj.keys.should == %w(job_class count count_working count_errored highest_error_count oldest_run_at)
23
+ qj.keys.should == %w(queue job_class count count_working count_errored highest_error_count oldest_run_at)
24
24
 
25
+ qj[:queue].should == ''
25
26
  qj[:job_class].should == 'Que::Job'
26
- qj[:count].should == '2'
27
- qj[:count_working].should == '1'
28
- qj[:count_errored].should == '1'
29
- qj[:highest_error_count].should == '5'
30
- Time.parse(qj[:oldest_run_at]).should be_within(3).of old
27
+ qj[:count].should == 2
28
+ qj[:count_working].should == 1
29
+ qj[:count_errored].should == 1
30
+ qj[:highest_error_count].should == 5
31
+ qj[:oldest_run_at].should be_within(3).of old
31
32
 
33
+ bj[:queue].should == ''
32
34
  bj[:job_class].should == 'BlockJob'
33
- bj[:count].should == '1'
34
- bj[:count_working].should == '0'
35
- bj[:count_errored].should == '0'
36
- bj[:highest_error_count].should == '0'
37
- Time.parse(bj[:oldest_run_at]).should be_within(3).of Time.now
35
+ bj[:count].should == 1
36
+ bj[:count_working].should == 0
37
+ bj[:count_errored].should == 0
38
+ bj[:highest_error_count].should == 0
39
+ bj[:oldest_run_at].should be_within(3).of Time.now
38
40
  ensure
39
41
  DB.get{pg_advisory_unlock_all{}}
40
42
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Que::Job, '.work' do
4
4
  it "should pass a job's arguments to the run method and delete it from the database" do
5
- ArgsJob.queue 1, 'two', {'three' => 3}
5
+ ArgsJob.enqueue 1, 'two', {'three' => 3}
6
6
  DB[:que_jobs].count.should be 1
7
7
 
8
8
  result = Que::Job.work
@@ -13,9 +13,38 @@ describe Que::Job, '.work' do
13
13
  $passed_args.should == [1, 'two', {'three' => 3}]
14
14
  end
15
15
 
16
+ it "should default to only working jobs without a named queue" do
17
+ Que::Job.enqueue 1, :queue => 'other_queue'
18
+ Que::Job.enqueue 2
19
+
20
+ result = Que::Job.work
21
+ result[:event].should == :job_worked
22
+ result[:job][:args].should == [2]
23
+
24
+ result = Que::Job.work
25
+ result[:event].should == :job_unavailable
26
+ end
27
+
28
+ it "should accept the name of a single queue to pull jobs from" do
29
+ Que::Job.enqueue 1, :queue => 'other_queue'
30
+ Que::Job.enqueue 2, :queue => 'other_queue'
31
+ Que::Job.enqueue 3
32
+
33
+ result = Que::Job.work(:other_queue)
34
+ result[:event].should == :job_worked
35
+ result[:job][:args].should == [1]
36
+
37
+ result = Que::Job.work('other_queue')
38
+ result[:event].should == :job_worked
39
+ result[:job][:args].should == [2]
40
+
41
+ result = Que::Job.work(:other_queue)
42
+ result[:event].should == :job_unavailable
43
+ end
44
+
16
45
  it "should make a job's argument hashes indifferently accessible" do
17
46
  DB[:que_jobs].count.should be 0
18
- ArgsJob.queue 1, 'two', {'array' => [{'number' => 3}]}
47
+ ArgsJob.enqueue 1, 'two', {'array' => [{'number' => 3}]}
19
48
  DB[:que_jobs].count.should be 1
20
49
 
21
50
  result = Que::Job.work
@@ -33,7 +62,7 @@ describe Que::Job, '.work' do
33
62
 
34
63
  it "should prefer a job with a higher priority" do
35
64
  # 1 is highest priority.
36
- [5, 4, 3, 2, 1, 2, 3, 4, 5].map{|p| Que::Job.queue :priority => p}
65
+ [5, 4, 3, 2, 1, 2, 3, 4, 5].map{|p| Que::Job.enqueue :priority => p}
37
66
  DB[:que_jobs].order(:job_id).select_map(:priority).should == [5, 4, 3, 2, 1, 2, 3, 4, 5]
38
67
 
39
68
  result = Que::Job.work
@@ -43,9 +72,9 @@ describe Que::Job, '.work' do
43
72
  end
44
73
 
45
74
  it "should prefer a job that was scheduled to run longer ago when priorities are equal" do
46
- Que::Job.queue :run_at => Time.now - 30
47
- Que::Job.queue :run_at => Time.now - 60
48
- Que::Job.queue :run_at => Time.now - 30
75
+ Que::Job.enqueue :run_at => Time.now - 30
76
+ Que::Job.enqueue :run_at => Time.now - 60
77
+ Que::Job.enqueue :run_at => Time.now - 30
49
78
 
50
79
  recent1, old, recent2 = DB[:que_jobs].order(:job_id).select_map(:run_at)
51
80
 
@@ -57,9 +86,9 @@ describe Que::Job, '.work' do
57
86
 
58
87
  it "should prefer a job that was queued earlier when priorities and run_ats are equal" do
59
88
  run_at = Time.now - 30
60
- Que::Job.queue :run_at => run_at
61
- Que::Job.queue :run_at => run_at
62
- Que::Job.queue :run_at => run_at
89
+ Que::Job.enqueue :run_at => run_at
90
+ Que::Job.enqueue :run_at => run_at
91
+ Que::Job.enqueue :run_at => run_at
63
92
 
64
93
  first, second, third = DB[:que_jobs].select_order_map(:job_id)
65
94
 
@@ -70,9 +99,9 @@ describe Que::Job, '.work' do
70
99
  end
71
100
 
72
101
  it "should only work a job whose scheduled time to run has passed" do
73
- Que::Job.queue :run_at => Time.now + 30
74
- Que::Job.queue :run_at => Time.now - 30
75
- Que::Job.queue :run_at => Time.now + 30
102
+ Que::Job.enqueue :run_at => Time.now + 30
103
+ Que::Job.enqueue :run_at => Time.now - 30
104
+ Que::Job.enqueue :run_at => Time.now + 30
76
105
 
77
106
  future1, past, future2 = DB[:que_jobs].order(:job_id).select_map(:run_at)
78
107
 
@@ -84,7 +113,7 @@ describe Que::Job, '.work' do
84
113
  end
85
114
 
86
115
  it "should lock the job it selects" do
87
- BlockJob.queue
116
+ BlockJob.enqueue
88
117
  id = DB[:que_jobs].get(:job_id)
89
118
  thread = Thread.new { Que::Job.work }
90
119
 
@@ -96,9 +125,9 @@ describe Que::Job, '.work' do
96
125
  end
97
126
 
98
127
  it "should skip jobs that are advisory-locked" do
99
- Que::Job.queue :priority => 2
100
- Que::Job.queue :priority => 1
101
- Que::Job.queue :priority => 3
128
+ Que::Job.enqueue :priority => 2
129
+ Que::Job.enqueue :priority => 1
130
+ Que::Job.enqueue :priority => 3
102
131
  id = DB[:que_jobs].where(:priority => 1).get(:job_id)
103
132
 
104
133
  begin
@@ -116,7 +145,7 @@ describe Que::Job, '.work' do
116
145
 
117
146
  it "should handle subclasses of other jobs" do
118
147
  class SubClassJob < Que::Job
119
- @default_priority = 2
148
+ @priority = 2
120
149
 
121
150
  def run
122
151
  $job_spec_result << :sub
@@ -124,7 +153,7 @@ describe Que::Job, '.work' do
124
153
  end
125
154
 
126
155
  class SubSubClassJob < SubClassJob
127
- @default_priority = 4
156
+ @priority = 4
128
157
 
129
158
  def run
130
159
  super
@@ -133,7 +162,7 @@ describe Que::Job, '.work' do
133
162
  end
134
163
 
135
164
  $job_spec_result = []
136
- SubClassJob.queue
165
+ SubClassJob.enqueue
137
166
  DB[:que_jobs].select_map(:priority).should == [2]
138
167
  result = Que::Job.work
139
168
  result[:event].should == :job_worked
@@ -141,7 +170,7 @@ describe Que::Job, '.work' do
141
170
  $job_spec_result.should == [:sub]
142
171
 
143
172
  $job_spec_result = []
144
- SubSubClassJob.queue
173
+ SubSubClassJob.enqueue
145
174
  DB[:que_jobs].select_map(:priority).should == [4]
146
175
  result = Que::Job.work
147
176
  result[:event].should == :job_worked
@@ -155,7 +184,7 @@ describe Que::Job, '.work' do
155
184
  end
156
185
  end
157
186
 
158
- ModuleJobModule::ModuleJob.queue
187
+ ModuleJobModule::ModuleJob.enqueue
159
188
  DB[:que_jobs].get(:job_class).should == "ModuleJobModule::ModuleJob"
160
189
 
161
190
  result = Que::Job.work
@@ -170,7 +199,7 @@ describe Que::Job, '.work' do
170
199
  end
171
200
  end
172
201
 
173
- DestroyJob.queue
202
+ DestroyJob.enqueue
174
203
  DB[:que_jobs].count.should be 1
175
204
  Que::Job.work
176
205
  DB[:que_jobs].count.should be 0
@@ -178,7 +207,7 @@ describe Que::Job, '.work' do
178
207
 
179
208
  describe "when encountering an error" do
180
209
  it "should exponentially back off the job" do
181
- ErrorJob.queue
210
+ ErrorJob.enqueue
182
211
 
183
212
  result = Que::Job.work
184
213
  result[:event].should == :job_errored
@@ -206,12 +235,78 @@ describe Que::Job, '.work' do
206
235
  job[:run_at].should be_within(3).of Time.now + 1299
207
236
  end
208
237
 
238
+ it "should respect a custom retry interval" do
239
+ class RetryIntervalJob < ErrorJob
240
+ @retry_interval = 5
241
+ end
242
+
243
+ RetryIntervalJob.enqueue
244
+
245
+ result = Que::Job.work
246
+ result[:event].should == :job_errored
247
+ result[:error].should be_an_instance_of RuntimeError
248
+ result[:job][:job_class].should == 'RetryIntervalJob'
249
+
250
+ DB[:que_jobs].count.should be 1
251
+ job = DB[:que_jobs].first
252
+ job[:error_count].should be 1
253
+ job[:last_error].should =~ /\AErrorJob!\n/
254
+ job[:run_at].should be_within(3).of Time.now + 5
255
+
256
+ DB[:que_jobs].update :error_count => 5,
257
+ :run_at => Time.now - 60
258
+
259
+ result = Que::Job.work
260
+ result[:event].should == :job_errored
261
+ result[:error].should be_an_instance_of RuntimeError
262
+ result[:job][:job_class].should == 'RetryIntervalJob'
263
+
264
+ DB[:que_jobs].count.should be 1
265
+ job = DB[:que_jobs].first
266
+ job[:error_count].should be 6
267
+ job[:last_error].should =~ /\AErrorJob!\n/
268
+ job[:run_at].should be_within(3).of Time.now + 5
269
+ end
270
+
271
+ it "should respect a custom retry interval formula" do
272
+ class RetryIntervalFormulaJob < ErrorJob
273
+ @retry_interval = proc { |count| count * 10 }
274
+ end
275
+
276
+ RetryIntervalFormulaJob.enqueue
277
+
278
+ result = Que::Job.work
279
+ result[:event].should == :job_errored
280
+ result[:error].should be_an_instance_of RuntimeError
281
+ result[:job][:job_class].should == 'RetryIntervalFormulaJob'
282
+
283
+ DB[:que_jobs].count.should be 1
284
+ job = DB[:que_jobs].first
285
+ job[:error_count].should be 1
286
+ job[:last_error].should =~ /\AErrorJob!\n/
287
+ job[:run_at].should be_within(3).of Time.now + 10
288
+
289
+ DB[:que_jobs].update :error_count => 5,
290
+ :run_at => Time.now - 60
291
+
292
+ result = Que::Job.work
293
+ result[:event].should == :job_errored
294
+ result[:error].should be_an_instance_of RuntimeError
295
+ result[:job][:job_class].should == 'RetryIntervalFormulaJob'
296
+
297
+ DB[:que_jobs].count.should be 1
298
+ job = DB[:que_jobs].first
299
+ job[:error_count].should be 6
300
+ job[:last_error].should =~ /\AErrorJob!\n/
301
+ job[:run_at].should be_within(3).of Time.now + 60
302
+ end
303
+
209
304
  it "should pass it to an error handler, if one is defined" do
210
305
  begin
211
306
  errors = []
212
307
  Que.error_handler = proc { |error| errors << error }
213
308
 
214
- ErrorJob.queue
309
+ ErrorJob.enqueue
215
310
 
216
311
  result = Que::Job.work
217
312
  result[:event].should == :job_errored
@@ -230,7 +325,7 @@ describe Que::Job, '.work' do
230
325
  it "should not do anything if the error handler itelf throws an error" do
231
326
  begin
232
327
  Que.error_handler = proc { |error| raise "Another error!" }
233
- ErrorJob.queue
328
+ ErrorJob.enqueue
234
329
 
235
330
  result = Que::Job.work
236
331
  result[:event].should == :job_errored