que 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +1 -1
- data/CHANGELOG.md +21 -1
- data/Gemfile +5 -0
- data/README.md +7 -6
- data/docs/advanced_setup.md +14 -4
- data/docs/customizing_que.md +4 -4
- data/docs/error_handling.md +13 -1
- data/docs/managing_workers.md +2 -2
- data/docs/migrating.md +26 -0
- data/docs/multiple_queues.md +13 -0
- data/docs/shutting_down_safely.md +7 -0
- data/docs/writing_reliable_jobs.md +43 -0
- data/lib/generators/que/templates/add_que.rb +1 -1
- data/lib/que.rb +27 -41
- data/lib/que/adapters/base.rb +75 -4
- data/lib/que/job.rb +45 -28
- data/lib/que/migrations.rb +3 -2
- data/lib/que/migrations/{1-down.sql → 1/down.sql} +0 -0
- data/lib/que/migrations/{1-up.sql → 1/up.sql} +0 -0
- data/lib/que/migrations/{2-down.sql → 2/down.sql} +0 -0
- data/lib/que/migrations/{2-up.sql → 2/up.sql} +0 -0
- data/lib/que/migrations/3/down.sql +5 -0
- data/lib/que/migrations/3/up.sql +5 -0
- data/lib/que/sql.rb +24 -17
- data/lib/que/version.rb +1 -1
- data/lib/que/worker.rb +6 -5
- data/spec/adapters/active_record_spec.rb +6 -6
- data/spec/adapters/sequel_spec.rb +4 -4
- data/spec/gemfiles/Gemfile1 +18 -0
- data/spec/gemfiles/Gemfile2 +18 -0
- data/spec/support/helpers.rb +2 -1
- data/spec/support/shared_examples/adapter.rb +7 -3
- data/spec/support/shared_examples/multi_threaded_adapter.rb +2 -2
- data/spec/travis.rb +12 -4
- data/spec/unit/customization_spec.rb +148 -0
- data/spec/unit/{queue_spec.rb → enqueue_spec.rb} +115 -14
- data/spec/unit/logging_spec.rb +3 -2
- data/spec/unit/migrations_spec.rb +3 -2
- data/spec/unit/pool_spec.rb +30 -6
- data/spec/unit/run_spec.rb +12 -0
- data/spec/unit/states_spec.rb +29 -31
- data/spec/unit/stats_spec.rb +16 -14
- data/spec/unit/work_spec.rb +120 -25
- data/spec/unit/worker_spec.rb +55 -9
- data/tasks/safe_shutdown.rb +1 -1
- metadata +30 -17
data/spec/unit/logging_spec.rb
CHANGED
@@ -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.
|
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[
|
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
|
|
data/spec/unit/pool_spec.rb
CHANGED
@@ -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.
|
23
|
-
$passed_args.should == [5, {
|
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.
|
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.
|
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.
|
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.
|
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
|
data/spec/unit/states_spec.rb
CHANGED
@@ -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[
|
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.
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
data/spec/unit/stats_spec.rb
CHANGED
@@ -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.
|
6
|
-
Que::Job.
|
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.
|
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 ==
|
27
|
-
qj[:count_working].should ==
|
28
|
-
qj[:count_errored].should ==
|
29
|
-
qj[:highest_error_count].should ==
|
30
|
-
|
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 ==
|
34
|
-
bj[:count_working].should ==
|
35
|
-
bj[:count_errored].should ==
|
36
|
-
bj[:highest_error_count].should ==
|
37
|
-
|
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
|
data/spec/unit/work_spec.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
47
|
-
Que::Job.
|
48
|
-
Que::Job.
|
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.
|
61
|
-
Que::Job.
|
62
|
-
Que::Job.
|
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.
|
74
|
-
Que::Job.
|
75
|
-
Que::Job.
|
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.
|
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.
|
100
|
-
Que::Job.
|
101
|
-
Que::Job.
|
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
|
-
@
|
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
|
-
@
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
328
|
+
ErrorJob.enqueue
|
234
329
|
|
235
330
|
result = Que::Job.work
|
236
331
|
result[:event].should == :job_errored
|