resque-mongo 1.4.0 → 1.8.1
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.
- data/CONTRIBUTORS +24 -6
- data/HISTORY.md +65 -0
- data/README.markdown +34 -5
- data/Rakefile +1 -1
- data/bin/resque +2 -2
- data/bin/resque-web +6 -1
- data/deps.rip +2 -2
- data/docs/HOOKS.md +121 -0
- data/docs/PLUGINS.md +93 -0
- data/examples/demo/Rakefile +5 -0
- data/examples/monit/resque.monit +6 -0
- data/lib/resque.rb +94 -7
- data/lib/resque/errors.rb +3 -0
- data/lib/resque/failure.rb +3 -0
- data/lib/resque/failure/base.rb +3 -0
- data/lib/resque/failure/hoptoad.rb +29 -19
- data/lib/resque/failure/mongo.rb +10 -1
- data/lib/resque/helpers.rb +8 -2
- data/lib/resque/job.rb +107 -2
- data/lib/resque/plugin.rb +46 -0
- data/lib/resque/server.rb +30 -11
- data/lib/resque/server/public/ranger.js +50 -7
- data/lib/resque/server/public/style.css +8 -1
- data/lib/resque/server/test_helper.rb +19 -0
- data/lib/resque/server/views/failed.erb +17 -3
- data/lib/resque/server/views/key_sets.erb +20 -0
- data/lib/resque/server/views/{key.erb → key_string.erb} +2 -8
- data/lib/resque/server/views/queues.erb +5 -2
- data/lib/resque/server/views/stats.erb +2 -2
- data/lib/resque/server/views/workers.erb +1 -1
- data/lib/resque/server/views/working.erb +2 -0
- data/lib/resque/tasks.rb +1 -1
- data/lib/resque/version.rb +1 -1
- data/lib/resque/worker.rb +54 -15
- data/tasks/redis.rake +53 -29
- data/test/job_hooks_test.rb +302 -0
- data/test/job_plugins_test.rb +209 -0
- data/test/plugin_test.rb +116 -0
- data/test/resque-mongo_benchmark.rb +62 -0
- data/test/resque-web_test.rb +54 -0
- data/test/resque_test.rb +34 -0
- data/test/test_helper.rb +15 -0
- data/test/worker_test.rb +62 -2
- metadata +58 -23
data/lib/resque/worker.rb
CHANGED
@@ -109,26 +109,25 @@ module Resque
|
|
109
109
|
|
110
110
|
if not @paused and job = reserve
|
111
111
|
log "got: #{job.inspect}"
|
112
|
+
run_hook :before_fork
|
113
|
+
working_on job
|
112
114
|
|
113
115
|
if @child = fork
|
114
116
|
rand # Reseeding
|
115
|
-
procline
|
116
|
-
$0 = procline
|
117
|
-
log! procline
|
117
|
+
procline "Forked #{@child} at #{Time.now.to_i}"
|
118
118
|
Process.wait
|
119
119
|
else
|
120
|
-
procline
|
121
|
-
|
122
|
-
log! procline
|
123
|
-
process(job, &block)
|
120
|
+
procline "Processing #{job.queue} since #{Time.now.to_i}"
|
121
|
+
perform(job, &block)
|
124
122
|
exit! unless @cant_fork
|
125
123
|
end
|
126
124
|
|
125
|
+
done_working
|
127
126
|
@child = nil
|
128
127
|
else
|
129
128
|
break if interval.to_i == 0
|
130
129
|
log! "Sleeping for #{interval.to_i}"
|
131
|
-
|
130
|
+
procline @paused ? "Paused" : "Waiting for #{@queues.join(',')}"
|
132
131
|
sleep interval.to_i
|
133
132
|
end
|
134
133
|
end
|
@@ -137,13 +136,21 @@ module Resque
|
|
137
136
|
unregister_worker
|
138
137
|
end
|
139
138
|
|
140
|
-
# Processes a single job. If none is given, it will
|
141
|
-
# one.
|
142
|
-
def process(job = nil)
|
139
|
+
# DEPRECATED. Processes a single job. If none is given, it will
|
140
|
+
# try to produce one. Usually run in the child.
|
141
|
+
def process(job = nil, &block)
|
143
142
|
return unless job ||= reserve
|
144
143
|
|
144
|
+
working_on job
|
145
|
+
perform(job, &block)
|
146
|
+
ensure
|
147
|
+
done_working
|
148
|
+
end
|
149
|
+
|
150
|
+
# Processes a given job in the child.
|
151
|
+
def perform(job)
|
145
152
|
begin
|
146
|
-
|
153
|
+
run_hook :after_fork, job
|
147
154
|
job.perform
|
148
155
|
rescue Object => e
|
149
156
|
log "#{job.inspect} failed: #{e.inspect}"
|
@@ -153,7 +160,6 @@ module Resque
|
|
153
160
|
log "done: #{job.inspect}"
|
154
161
|
ensure
|
155
162
|
yield job if block_given?
|
156
|
-
done_working
|
157
163
|
end
|
158
164
|
end
|
159
165
|
|
@@ -203,7 +209,12 @@ module Resque
|
|
203
209
|
enable_gc_optimizations
|
204
210
|
register_signal_handlers
|
205
211
|
prune_dead_workers
|
212
|
+
run_hook :before_first_fork
|
206
213
|
register_worker
|
214
|
+
|
215
|
+
# Fix buffering so we can `rake resque:work > resque.log` and
|
216
|
+
# get output from the child in there.
|
217
|
+
$stdout.sync = true
|
207
218
|
end
|
208
219
|
|
209
220
|
# Enables GC Optimizations if you're running REE.
|
@@ -307,8 +318,28 @@ module Resque
|
|
307
318
|
started!
|
308
319
|
end
|
309
320
|
|
321
|
+
# Runs a named hook, passing along any arguments.
|
322
|
+
def run_hook(name, *args)
|
323
|
+
return unless hook = Resque.send(name)
|
324
|
+
msg = "Running #{name} hook"
|
325
|
+
msg << " with #{args.inspect}" if args.any?
|
326
|
+
log msg
|
327
|
+
|
328
|
+
args.any? ? hook.call(*args) : hook.call
|
329
|
+
end
|
330
|
+
|
310
331
|
# Unregisters ourself as a worker. Useful when shutting down.
|
311
332
|
def unregister_worker
|
333
|
+
# If we're still processing a job, make sure it gets logged as a
|
334
|
+
# failure.
|
335
|
+
if (hash = processing) && !hash.empty?
|
336
|
+
job = Job.new(hash['queue'], hash['payload'])
|
337
|
+
# Ensure the proper worker is attached to this job, even if
|
338
|
+
# it's not the precise instance that died.
|
339
|
+
job.worker = self
|
340
|
+
job.fail(DirtyExit.new)
|
341
|
+
end
|
342
|
+
|
312
343
|
mongo_workers.remove(:worker => self.to_s)
|
313
344
|
|
314
345
|
Stat.clear("processed:#{self}")
|
@@ -318,13 +349,13 @@ module Resque
|
|
318
349
|
# Given a job, tells Redis we're working on it. Useful for seeing
|
319
350
|
# what workers are doing and when.
|
320
351
|
def working_on(job)
|
321
|
-
job.worker = self
|
352
|
+
job.worker = self
|
322
353
|
data = encode \
|
323
354
|
:queue => job.queue,
|
324
355
|
:run_at => Time.now.to_s,
|
325
356
|
:payload => job.payload
|
326
357
|
working_on = {'working_on' => data}
|
327
|
-
mongo_workers.update({:worker => self.to_s}, {'$set' => working_on})
|
358
|
+
mongo_workers.update({:worker => self.to_s}, {'$set' => working_on}, :upsert => true )
|
328
359
|
end
|
329
360
|
|
330
361
|
# Called when we are done working - clears our `working_on` state
|
@@ -424,6 +455,14 @@ module Resque
|
|
424
455
|
end
|
425
456
|
end
|
426
457
|
|
458
|
+
# Given a string, sets the procline ($0) and logs.
|
459
|
+
# Procline is always in the format of:
|
460
|
+
# resque-VERSION: STRING
|
461
|
+
def procline(string)
|
462
|
+
$0 = "resque-#{Resque::Version}: #{string}"
|
463
|
+
log! $0
|
464
|
+
end
|
465
|
+
|
427
466
|
# Log a message to STDOUT if we are verbose or very_verbose.
|
428
467
|
def log(message)
|
429
468
|
if verbose
|
data/tasks/redis.rake
CHANGED
@@ -1,20 +1,28 @@
|
|
1
1
|
# Inspired by rabbitmq.rake the Redbox project at http://github.com/rick/redbox/tree/master
|
2
2
|
require 'fileutils'
|
3
3
|
require 'open-uri'
|
4
|
+
require 'pathname'
|
4
5
|
|
5
6
|
class RedisRunner
|
6
7
|
|
7
|
-
def self.
|
8
|
-
|
8
|
+
def self.redis_dir
|
9
|
+
@redis_dir ||= if ENV['PREFIX']
|
10
|
+
Pathname.new(ENV['PREFIX'])
|
11
|
+
else
|
12
|
+
Pathname.new(`which redis-server`) + '..' + '..'
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
|
-
def self.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def self.bin_dir
|
17
|
+
redis_dir + 'bin'
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config
|
21
|
+
@config ||= if File.exists?(redis_dir + 'etc/redis.conf')
|
22
|
+
redis_dir + 'etc/redis.conf'
|
23
|
+
else
|
24
|
+
redis_dir + '../etc/redis.conf'
|
25
|
+
end
|
18
26
|
end
|
19
27
|
|
20
28
|
def self.dtach_socket
|
@@ -29,12 +37,12 @@ class RedisRunner
|
|
29
37
|
def self.start
|
30
38
|
puts 'Detach with Ctrl+\ Re-attach with rake redis:attach'
|
31
39
|
sleep 1
|
32
|
-
command = "dtach -A #{dtach_socket} redis-server #{
|
40
|
+
command = "#{bin_dir}/dtach -A #{dtach_socket} #{bin_dir}/redis-server #{config}"
|
33
41
|
sh command
|
34
42
|
end
|
35
43
|
|
36
44
|
def self.attach
|
37
|
-
exec "dtach -a #{dtach_socket}"
|
45
|
+
exec "#{bin_dir}/dtach -a #{dtach_socket}"
|
38
46
|
end
|
39
47
|
|
40
48
|
def self.stop
|
@@ -73,31 +81,39 @@ namespace :redis do
|
|
73
81
|
|
74
82
|
desc 'Install the latest verison of Redis from Github (requires git, duh)'
|
75
83
|
task :install => [:about, :download, :make] do
|
76
|
-
|
84
|
+
bin_dir = '/usr/bin'
|
85
|
+
conf_dir = '/etc'
|
86
|
+
|
87
|
+
if ENV['PREFIX']
|
88
|
+
bin_dir = "#{ENV['PREFIX']}/bin"
|
89
|
+
sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
|
90
|
+
|
91
|
+
conf_dir = "#{ENV['PREFIX']}/etc"
|
92
|
+
sh "mkdir -p #{conf_dir}" unless File.exists?("#{conf_dir}")
|
93
|
+
end
|
94
|
+
|
77
95
|
%w(redis-benchmark redis-cli redis-server).each do |bin|
|
78
96
|
sh "cp /tmp/redis/#{bin} #{bin_dir}"
|
79
97
|
end
|
80
98
|
|
81
99
|
puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}"
|
82
100
|
|
83
|
-
ENV['PREFIX'] and conf_dir = "#{ENV['PREFIX']}/etc" or conf_dir = '/etc'
|
84
101
|
unless File.exists?("#{conf_dir}/redis.conf")
|
85
|
-
sh "mkdir #{conf_dir}" unless File.exists?("#{conf_dir}")
|
86
102
|
sh "cp /tmp/redis/redis.conf #{conf_dir}/redis.conf"
|
87
103
|
puts "Installed redis.conf to #{conf_dir} \n You should look at this file!"
|
88
104
|
end
|
89
105
|
end
|
90
106
|
|
91
107
|
task :make do
|
92
|
-
sh "cd
|
93
|
-
sh "cd
|
108
|
+
sh "cd /tmp/redis && make clean"
|
109
|
+
sh "cd /tmp/redis && make"
|
94
110
|
end
|
95
111
|
|
96
112
|
desc "Download package"
|
97
113
|
task :download do
|
98
|
-
sh 'rm -rf /tmp/redis/' if File.exists?("
|
99
|
-
sh 'git clone git://github.com/antirez/redis.git /tmp/redis' unless File.exists?(
|
100
|
-
sh "cd
|
114
|
+
sh 'rm -rf /tmp/redis/' if File.exists?("/tmp/redis/.svn")
|
115
|
+
sh 'git clone git://github.com/antirez/redis.git /tmp/redis' unless File.exists?('/tmp/redis')
|
116
|
+
sh "cd /tmp/redis && git pull" if File.exists?("/tmp/redis/.git")
|
101
117
|
end
|
102
118
|
|
103
119
|
end
|
@@ -110,9 +126,24 @@ namespace :dtach do
|
|
110
126
|
end
|
111
127
|
|
112
128
|
desc 'Install dtach 0.8 from source'
|
113
|
-
task :install => [:about] do
|
129
|
+
task :install => [:about, :download, :make] do
|
130
|
+
|
131
|
+
bin_dir = "/usr/bin"
|
132
|
+
|
133
|
+
if ENV['PREFIX']
|
134
|
+
bin_dir = "#{ENV['PREFIX']}/bin"
|
135
|
+
sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
|
136
|
+
end
|
137
|
+
|
138
|
+
sh "cp /tmp/dtach-0.8/dtach #{bin_dir}"
|
139
|
+
end
|
140
|
+
|
141
|
+
task :make do
|
142
|
+
sh 'cd /tmp/dtach-0.8/ && ./configure && make'
|
143
|
+
end
|
114
144
|
|
115
|
-
|
145
|
+
desc "Download package"
|
146
|
+
task :download do
|
116
147
|
unless File.exists?('/tmp/dtach-0.8.tar.gz')
|
117
148
|
require 'net/http'
|
118
149
|
|
@@ -121,15 +152,8 @@ namespace :dtach do
|
|
121
152
|
end
|
122
153
|
|
123
154
|
unless File.directory?('/tmp/dtach-0.8')
|
124
|
-
|
155
|
+
sh 'cd /tmp && tar xzf dtach-0.8.tar.gz'
|
125
156
|
end
|
126
|
-
|
127
|
-
ENV['PREFIX'] and bin_dir = "#{ENV['PREFIX']}/bin" or bin_dir = "/usr/bin"
|
128
|
-
Dir.chdir('/tmp/dtach-0.8/')
|
129
|
-
sh 'cd /tmp/dtach-0.8/ && ./configure && make'
|
130
|
-
sh "cp /tmp/dtach-0.8/dtach #{bin_dir}"
|
131
|
-
|
132
|
-
puts "Dtach successfully installed to #{bin_dir}"
|
133
157
|
end
|
134
158
|
end
|
135
159
|
|
@@ -0,0 +1,302 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
context "Resque::Job before_perform" do
|
4
|
+
include PerformJob
|
5
|
+
|
6
|
+
class BeforePerformJob
|
7
|
+
def self.before_perform_record_history(history)
|
8
|
+
history << :before_perform
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.perform(history)
|
12
|
+
history << :perform
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
test "it runs before_perform before perform" do
|
17
|
+
result = perform_job(BeforePerformJob, history=[])
|
18
|
+
assert_equal true, result, "perform returned true"
|
19
|
+
assert_equal history, [:before_perform, :perform]
|
20
|
+
end
|
21
|
+
|
22
|
+
class BeforePerformJobFails
|
23
|
+
def self.before_perform_fail_job(history)
|
24
|
+
history << :before_perform
|
25
|
+
raise StandardError
|
26
|
+
end
|
27
|
+
def self.perform(history)
|
28
|
+
history << :perform
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
test "raises an error and does not perform if before_perform fails" do
|
33
|
+
history = []
|
34
|
+
assert_raises StandardError do
|
35
|
+
perform_job(BeforePerformJobFails, history)
|
36
|
+
end
|
37
|
+
assert_equal history, [:before_perform], "Only before_perform was run"
|
38
|
+
end
|
39
|
+
|
40
|
+
class BeforePerformJobAborts
|
41
|
+
def self.before_perform_abort(history)
|
42
|
+
history << :before_perform
|
43
|
+
raise Resque::Job::DontPerform
|
44
|
+
end
|
45
|
+
def self.perform(history)
|
46
|
+
history << :perform
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
test "does not perform if before_perform raises Resque::Job::DontPerform" do
|
51
|
+
result = perform_job(BeforePerformJobAborts, history=[])
|
52
|
+
assert_equal false, result, "perform returned false"
|
53
|
+
assert_equal history, [:before_perform], "Only before_perform was run"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "Resque::Job after_perform" do
|
58
|
+
include PerformJob
|
59
|
+
|
60
|
+
class AfterPerformJob
|
61
|
+
def self.perform(history)
|
62
|
+
history << :perform
|
63
|
+
end
|
64
|
+
def self.after_perform_record_history(history)
|
65
|
+
history << :after_perform
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
test "it runs after_perform after perform" do
|
70
|
+
result = perform_job(AfterPerformJob, history=[])
|
71
|
+
assert_equal true, result, "perform returned true"
|
72
|
+
assert_equal history, [:perform, :after_perform]
|
73
|
+
end
|
74
|
+
|
75
|
+
class AfterPerformJobFails
|
76
|
+
def self.perform(history)
|
77
|
+
history << :perform
|
78
|
+
end
|
79
|
+
def self.after_perform_fail_job(history)
|
80
|
+
history << :after_perform
|
81
|
+
raise StandardError
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
test "raises an error but has already performed if after_perform fails" do
|
86
|
+
history = []
|
87
|
+
assert_raises StandardError do
|
88
|
+
perform_job(AfterPerformJobFails, history)
|
89
|
+
end
|
90
|
+
assert_equal history, [:perform, :after_perform], "Only after_perform was run"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "Resque::Job around_perform" do
|
95
|
+
include PerformJob
|
96
|
+
|
97
|
+
class AroundPerformJob
|
98
|
+
def self.perform(history)
|
99
|
+
history << :perform
|
100
|
+
end
|
101
|
+
def self.around_perform_record_history(history)
|
102
|
+
history << :start_around_perform
|
103
|
+
yield
|
104
|
+
history << :finish_around_perform
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
test "it runs around_perform then yields in order to perform" do
|
109
|
+
result = perform_job(AroundPerformJob, history=[])
|
110
|
+
assert_equal true, result, "perform returned true"
|
111
|
+
assert_equal history, [:start_around_perform, :perform, :finish_around_perform]
|
112
|
+
end
|
113
|
+
|
114
|
+
class AroundPerformJobFailsBeforePerforming
|
115
|
+
def self.perform(history)
|
116
|
+
history << :perform
|
117
|
+
end
|
118
|
+
def self.around_perform_fail(history)
|
119
|
+
history << :start_around_perform
|
120
|
+
raise StandardError
|
121
|
+
yield
|
122
|
+
history << :finish_around_perform
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
test "raises an error and does not perform if around_perform fails before yielding" do
|
127
|
+
history = []
|
128
|
+
assert_raises StandardError do
|
129
|
+
perform_job(AroundPerformJobFailsBeforePerforming, history)
|
130
|
+
end
|
131
|
+
assert_equal history, [:start_around_perform], "Only part of around_perform was run"
|
132
|
+
end
|
133
|
+
|
134
|
+
class AroundPerformJobFailsWhilePerforming
|
135
|
+
def self.perform(history)
|
136
|
+
history << :perform
|
137
|
+
raise StandardError
|
138
|
+
end
|
139
|
+
def self.around_perform_fail_in_yield(history)
|
140
|
+
history << :start_around_perform
|
141
|
+
begin
|
142
|
+
yield
|
143
|
+
ensure
|
144
|
+
history << :ensure_around_perform
|
145
|
+
end
|
146
|
+
history << :finish_around_perform
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
test "raises an error but may handle exceptions if perform fails" do
|
151
|
+
history = []
|
152
|
+
assert_raises StandardError do
|
153
|
+
perform_job(AroundPerformJobFailsWhilePerforming, history)
|
154
|
+
end
|
155
|
+
assert_equal history, [:start_around_perform, :perform, :ensure_around_perform], "Only part of around_perform was run"
|
156
|
+
end
|
157
|
+
|
158
|
+
class AroundPerformJobDoesNotHaveToYield
|
159
|
+
def self.perform(history)
|
160
|
+
history << :perform
|
161
|
+
end
|
162
|
+
def self.around_perform_dont_yield(history)
|
163
|
+
history << :start_around_perform
|
164
|
+
history << :finish_around_perform
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
test "around_perform is not required to yield" do
|
169
|
+
history = []
|
170
|
+
result = perform_job(AroundPerformJobDoesNotHaveToYield, history)
|
171
|
+
assert_equal false, result, "perform returns false"
|
172
|
+
assert_equal history, [:start_around_perform, :finish_around_perform], "perform was not run"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "Resque::Job on_failure" do
|
177
|
+
include PerformJob
|
178
|
+
|
179
|
+
class FailureJobThatDoesNotFail
|
180
|
+
def self.perform(history)
|
181
|
+
history << :perform
|
182
|
+
end
|
183
|
+
def self.on_failure_record_failure(exception, history)
|
184
|
+
history << exception.message
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
test "it does not call on_failure if no failures occur" do
|
189
|
+
result = perform_job(FailureJobThatDoesNotFail, history=[])
|
190
|
+
assert_equal true, result, "perform returned true"
|
191
|
+
assert_equal history, [:perform]
|
192
|
+
end
|
193
|
+
|
194
|
+
class FailureJobThatFails
|
195
|
+
def self.perform(history)
|
196
|
+
history << :perform
|
197
|
+
raise StandardError, "oh no"
|
198
|
+
end
|
199
|
+
def self.on_failure_record_failure(exception, history)
|
200
|
+
history << exception.message
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
test "it calls on_failure with the exception and then re-raises the exception" do
|
205
|
+
history = []
|
206
|
+
assert_raises StandardError do
|
207
|
+
perform_job(FailureJobThatFails, history)
|
208
|
+
end
|
209
|
+
assert_equal history, [:perform, "oh no"]
|
210
|
+
end
|
211
|
+
|
212
|
+
class FailureJobThatFailsBadly
|
213
|
+
def self.perform(history)
|
214
|
+
history << :perform
|
215
|
+
raise SyntaxError, "oh no"
|
216
|
+
end
|
217
|
+
def self.on_failure_record_failure(exception, history)
|
218
|
+
history << exception.message
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
test "it calls on_failure even with bad exceptions" do
|
223
|
+
history = []
|
224
|
+
assert_raises SyntaxError do
|
225
|
+
perform_job(FailureJobThatFailsBadly, history)
|
226
|
+
end
|
227
|
+
assert_equal history, [:perform, "oh no"]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context "Resque::Job all hooks" do
|
232
|
+
include PerformJob
|
233
|
+
|
234
|
+
class VeryHookyJob
|
235
|
+
def self.before_perform_record_history(history)
|
236
|
+
history << :before_perform
|
237
|
+
end
|
238
|
+
def self.around_perform_record_history(history)
|
239
|
+
history << :start_around_perform
|
240
|
+
yield
|
241
|
+
history << :finish_around_perform
|
242
|
+
end
|
243
|
+
def self.perform(history)
|
244
|
+
history << :perform
|
245
|
+
end
|
246
|
+
def self.after_perform_record_history(history)
|
247
|
+
history << :after_perform
|
248
|
+
end
|
249
|
+
def self.on_failure_record_history(exception, history)
|
250
|
+
history << exception.message
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
test "the complete hook order" do
|
255
|
+
result = perform_job(VeryHookyJob, history=[])
|
256
|
+
assert_equal true, result, "perform returned true"
|
257
|
+
assert_equal history, [
|
258
|
+
:before_perform,
|
259
|
+
:start_around_perform,
|
260
|
+
:perform,
|
261
|
+
:finish_around_perform,
|
262
|
+
:after_perform
|
263
|
+
]
|
264
|
+
end
|
265
|
+
|
266
|
+
class VeryHookyJobThatFails
|
267
|
+
def self.before_perform_record_history(history)
|
268
|
+
history << :before_perform
|
269
|
+
end
|
270
|
+
def self.around_perform_record_history(history)
|
271
|
+
history << :start_around_perform
|
272
|
+
yield
|
273
|
+
history << :finish_around_perform
|
274
|
+
end
|
275
|
+
def self.perform(history)
|
276
|
+
history << :perform
|
277
|
+
end
|
278
|
+
def self.after_perform_record_history(history)
|
279
|
+
history << :after_perform
|
280
|
+
raise StandardError, "oh no"
|
281
|
+
end
|
282
|
+
def self.on_failure_record_history(exception, history)
|
283
|
+
history << exception.message
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
test "the complete hook order with a failure at the last minute" do
|
288
|
+
history = []
|
289
|
+
assert_raises StandardError do
|
290
|
+
perform_job(VeryHookyJobThatFails, history)
|
291
|
+
end
|
292
|
+
assert_equal history, [
|
293
|
+
:before_perform,
|
294
|
+
:start_around_perform,
|
295
|
+
:perform,
|
296
|
+
:finish_around_perform,
|
297
|
+
:after_perform,
|
298
|
+
"oh no"
|
299
|
+
]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|