resque 1.23.0 → 2.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 +7 -0
- data/HISTORY.md +271 -0
- data/README.markdown +454 -484
- data/Rakefile +4 -17
- data/bin/resque-web +10 -22
- data/lib/resque/data_store.rb +335 -0
- data/lib/resque/errors.rb +15 -1
- data/lib/resque/failure/airbrake.rb +32 -4
- data/lib/resque/failure/base.rb +16 -7
- data/lib/resque/failure/multiple.rb +26 -8
- data/lib/resque/failure/redis.rb +92 -15
- data/lib/resque/failure/redis_multi_queue.rb +104 -0
- data/lib/resque/failure.rb +62 -32
- data/lib/resque/helpers.rb +11 -57
- data/lib/resque/job.rb +79 -12
- data/lib/resque/log_formatters/quiet_formatter.rb +7 -0
- data/lib/resque/log_formatters/verbose_formatter.rb +7 -0
- data/lib/resque/log_formatters/very_verbose_formatter.rb +8 -0
- data/lib/resque/logging.rb +18 -0
- data/lib/resque/plugin.rb +22 -10
- data/lib/resque/railtie.rb +10 -0
- data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
- data/lib/resque/server/public/jquery.relatize_date.js +4 -4
- data/lib/resque/server/public/main.js +3 -0
- data/lib/resque/server/public/ranger.js +16 -8
- data/lib/resque/server/public/style.css +13 -8
- data/lib/resque/server/views/error.erb +1 -1
- data/lib/resque/server/views/failed.erb +27 -59
- data/lib/resque/server/views/failed_job.erb +50 -0
- data/lib/resque/server/views/failed_queues_overview.erb +24 -0
- data/lib/resque/server/views/job_class.erb +8 -0
- data/lib/resque/server/views/key_sets.erb +2 -4
- data/lib/resque/server/views/key_string.erb +1 -1
- data/lib/resque/server/views/layout.erb +7 -6
- data/lib/resque/server/views/next_more.erb +22 -10
- data/lib/resque/server/views/processing.erb +2 -0
- data/lib/resque/server/views/queues.erb +22 -13
- data/lib/resque/server/views/stats.erb +5 -5
- data/lib/resque/server/views/workers.erb +4 -4
- data/lib/resque/server/views/working.erb +10 -11
- data/lib/resque/server.rb +51 -108
- data/lib/resque/server_helper.rb +185 -0
- data/lib/resque/stat.rb +19 -7
- data/lib/resque/tasks.rb +26 -25
- data/lib/resque/thread_signal.rb +24 -0
- data/lib/resque/vendor/utf8_util.rb +2 -8
- data/lib/resque/version.rb +1 -1
- data/lib/resque/web_runner.rb +374 -0
- data/lib/resque/worker.rb +487 -163
- data/lib/resque.rb +332 -52
- data/lib/tasks/redis.rake +11 -11
- metadata +169 -149
- data/lib/resque/failure/hoptoad.rb +0 -33
- data/lib/resque/failure/thoughtbot.rb +0 -33
- data/lib/resque/server/public/jquery-1.3.2.min.js +0 -19
- data/lib/resque/server/test_helper.rb +0 -19
- data/lib/resque/vendor/utf8_util/utf8_util_18.rb +0 -91
- data/lib/resque/vendor/utf8_util/utf8_util_19.rb +0 -5
- data/test/airbrake_test.rb +0 -27
- data/test/hoptoad_test.rb +0 -26
- data/test/job_hooks_test.rb +0 -464
- data/test/job_plugins_test.rb +0 -230
- data/test/plugin_test.rb +0 -116
- data/test/redis-test-cluster.conf +0 -115
- data/test/redis-test.conf +0 -115
- data/test/resque-web_test.rb +0 -59
- data/test/resque_failure_redis_test.rb +0 -19
- data/test/resque_test.rb +0 -278
- data/test/test_helper.rb +0 -178
- data/test/worker_test.rb +0 -657
data/lib/resque/failure/redis.rb
CHANGED
@@ -3,9 +3,18 @@ module Resque
|
|
3
3
|
# A Failure backend that stores exceptions in Redis. Very simple but
|
4
4
|
# works out of the box, along with support in the Resque web app.
|
5
5
|
class Redis < Base
|
6
|
+
|
7
|
+
def data_store
|
8
|
+
Resque.data_store
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.data_store
|
12
|
+
Resque.data_store
|
13
|
+
end
|
14
|
+
|
6
15
|
def save
|
7
16
|
data = {
|
8
|
-
:failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"),
|
17
|
+
:failed_at => UTF8Util.clean(Time.now.strftime("%Y/%m/%d %H:%M:%S %Z")),
|
9
18
|
:payload => payload,
|
10
19
|
:exception => exception.class.to_s,
|
11
20
|
:error => UTF8Util.clean(exception.to_s),
|
@@ -14,38 +23,106 @@ module Resque
|
|
14
23
|
:queue => queue
|
15
24
|
}
|
16
25
|
data = Resque.encode(data)
|
17
|
-
|
26
|
+
data_store.push_to_failed_queue(data)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.count(queue = nil, class_name = nil)
|
30
|
+
check_queue(queue)
|
31
|
+
|
32
|
+
if class_name
|
33
|
+
n = 0
|
34
|
+
each(0, count(queue), queue, class_name) { n += 1 }
|
35
|
+
n
|
36
|
+
else
|
37
|
+
data_store.num_failed
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.queues
|
42
|
+
data_store.failed_queue_names
|
18
43
|
end
|
19
44
|
|
20
|
-
def self.
|
21
|
-
|
45
|
+
def self.all(offset = 0, limit = 1, queue = nil)
|
46
|
+
check_queue(queue)
|
47
|
+
Resque.list_range(:failed, offset, limit)
|
22
48
|
end
|
23
49
|
|
24
|
-
def self.
|
25
|
-
|
50
|
+
def self.each(offset = 0, limit = self.count, queue = :failed, class_name = nil, order = 'desc')
|
51
|
+
if class_name
|
52
|
+
original_limit = limit
|
53
|
+
limit = count
|
54
|
+
end
|
55
|
+
all_items = limit == 1 ? [all(offset,limit,queue)] : Array(all(offset, limit, queue))
|
56
|
+
reversed = false
|
57
|
+
if order.eql? 'desc'
|
58
|
+
all_items.reverse!
|
59
|
+
reversed = true
|
60
|
+
end
|
61
|
+
all_items.each_with_index do |item, i|
|
62
|
+
if !class_name || (item['payload'] && item['payload']['class'] == class_name && (original_limit -= 1) >= 0)
|
63
|
+
if reversed
|
64
|
+
id = (all_items.length - 1) + (offset - i)
|
65
|
+
else
|
66
|
+
id = offset + i
|
67
|
+
end
|
68
|
+
yield id, item
|
69
|
+
end
|
70
|
+
end
|
26
71
|
end
|
27
72
|
|
28
|
-
def self.clear
|
29
|
-
|
73
|
+
def self.clear(queue = nil)
|
74
|
+
check_queue(queue)
|
75
|
+
data_store.clear_failed_queue
|
30
76
|
end
|
31
77
|
|
32
|
-
def self.requeue(
|
33
|
-
|
78
|
+
def self.requeue(id, queue = nil)
|
79
|
+
check_queue(queue)
|
80
|
+
item = all(id)
|
34
81
|
item['retried_at'] = Time.now.strftime("%Y/%m/%d %H:%M:%S")
|
35
|
-
|
82
|
+
data_store.update_item_in_failed_queue(id,Resque.encode(item))
|
36
83
|
Job.create(item['queue'], item['payload']['class'], *item['payload']['args'])
|
37
84
|
end
|
38
85
|
|
39
|
-
def self.remove(
|
40
|
-
|
41
|
-
|
42
|
-
|
86
|
+
def self.remove(id, queue = nil)
|
87
|
+
check_queue(queue)
|
88
|
+
data_store.remove_from_failed_queue(id, queue)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.requeue_queue(queue)
|
92
|
+
i = 0
|
93
|
+
while job = all(i)
|
94
|
+
requeue(i) if job['queue'] == queue
|
95
|
+
i += 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.requeue_all
|
100
|
+
count.times do |num|
|
101
|
+
requeue(num)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.remove_queue(queue)
|
106
|
+
i = 0
|
107
|
+
while job = all(i)
|
108
|
+
if job['queue'] == queue
|
109
|
+
# This will remove the failure from the array so do not increment the index.
|
110
|
+
remove(i)
|
111
|
+
else
|
112
|
+
i += 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.check_queue(queue)
|
118
|
+
raise ArgumentError, "invalid queue: #{queue}" if queue && queue.to_s != "failed"
|
43
119
|
end
|
44
120
|
|
45
121
|
def filter_backtrace(backtrace)
|
46
122
|
index = backtrace.index { |item| item.include?('/lib/resque/job.rb') }
|
47
123
|
backtrace.first(index.to_i)
|
48
124
|
end
|
125
|
+
|
49
126
|
end
|
50
127
|
end
|
51
128
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Resque
|
2
|
+
module Failure
|
3
|
+
# A Failure backend that stores exceptions in Redis. Very simple but
|
4
|
+
# works out of the box, along with support in the Resque web app.
|
5
|
+
class RedisMultiQueue < Base
|
6
|
+
|
7
|
+
def data_store
|
8
|
+
Resque.data_store
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.data_store
|
12
|
+
Resque.data_store
|
13
|
+
end
|
14
|
+
|
15
|
+
def save
|
16
|
+
data = {
|
17
|
+
:failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"),
|
18
|
+
:payload => payload,
|
19
|
+
:exception => exception.class.to_s,
|
20
|
+
:error => UTF8Util.clean(exception.to_s),
|
21
|
+
:backtrace => filter_backtrace(Array(exception.backtrace)),
|
22
|
+
:worker => worker.to_s,
|
23
|
+
:queue => queue
|
24
|
+
}
|
25
|
+
data = Resque.encode(data)
|
26
|
+
data_store.push_to_failed_queue(data,Resque::Failure.failure_queue_name(queue))
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.count(queue = nil, class_name = nil)
|
30
|
+
if queue
|
31
|
+
if class_name
|
32
|
+
n = 0
|
33
|
+
each(0, count(queue), queue, class_name) { n += 1 }
|
34
|
+
n
|
35
|
+
else
|
36
|
+
data_store.num_failed(queue).to_i
|
37
|
+
end
|
38
|
+
else
|
39
|
+
total = 0
|
40
|
+
queues.each { |q| total += count(q) }
|
41
|
+
total
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.all(offset = 0, limit = 1, queue = :failed)
|
46
|
+
Resque.list_range(queue, offset, limit)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.queues
|
50
|
+
data_store.failed_queue_names(:failed_queues)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.each(offset = 0, limit = self.count, queue = :failed, class_name = nil, order = 'desc')
|
54
|
+
items = all(offset, limit, queue)
|
55
|
+
items = [items] unless items.is_a? Array
|
56
|
+
reversed = false
|
57
|
+
if order.eql? 'desc'
|
58
|
+
items.reverse!
|
59
|
+
reversed = true
|
60
|
+
end
|
61
|
+
items.each_with_index do |item, i|
|
62
|
+
if !class_name || (item['payload'] && item['payload']['class'] == class_name)
|
63
|
+
id = reversed ? (items.length - 1) + (offset - i) : offset + i
|
64
|
+
yield id, item
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.clear(queue = :failed)
|
70
|
+
queues = queue ? Array(queue) : self.queues
|
71
|
+
queues.each { |queue| data_store.clear_failed_queue(queue) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.requeue(id, queue = :failed)
|
75
|
+
item = all(id, 1, queue)
|
76
|
+
item['retried_at'] = Time.now.strftime("%Y/%m/%d %H:%M:%S")
|
77
|
+
data_store.update_item_in_failed_queue(id,Resque.encode(item),queue)
|
78
|
+
Job.create(item['queue'], item['payload']['class'], *item['payload']['args'])
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.remove(id, queue = :failed)
|
82
|
+
data_store.remove_from_failed_queue(id,queue)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.requeue_queue(queue)
|
86
|
+
failure_queue = Resque::Failure.failure_queue_name(queue)
|
87
|
+
each(0, count(failure_queue), failure_queue) { |id, _| requeue(id, failure_queue) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.requeue_all
|
91
|
+
queues.each { |queue| requeue_queue(Resque::Failure.job_queue_name(queue)) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.remove_queue(queue)
|
95
|
+
data_store.remove_failed_queue(Resque::Failure.failure_queue_name(queue))
|
96
|
+
end
|
97
|
+
|
98
|
+
def filter_backtrace(backtrace)
|
99
|
+
index = backtrace.index { |item| item.include?('/lib/resque/job.rb') }
|
100
|
+
backtrace.first(index.to_i)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/resque/failure.rb
CHANGED
@@ -22,31 +22,63 @@ module Resque
|
|
22
22
|
# `Resque::Failure::Base`.
|
23
23
|
#
|
24
24
|
# Example use:
|
25
|
-
# require 'resque/failure/
|
26
|
-
# Resque::Failure.backend = Resque::Failure::
|
25
|
+
# require 'resque/failure/airbrake'
|
26
|
+
# Resque::Failure.backend = Resque::Failure::Airbrake
|
27
27
|
def self.backend=(backend)
|
28
28
|
@backend = backend
|
29
29
|
end
|
30
|
+
self.backend = nil
|
30
31
|
|
31
32
|
# Returns the current backend class. If none has been set, falls
|
32
33
|
# back to `Resque::Failure::Redis`
|
33
34
|
def self.backend
|
34
35
|
return @backend if @backend
|
35
|
-
|
36
|
-
|
36
|
+
|
37
|
+
case ENV['FAILURE_BACKEND']
|
38
|
+
when 'redis_multi_queue'
|
39
|
+
require 'resque/failure/redis_multi_queue'
|
40
|
+
@backend = Failure::RedisMultiQueue
|
41
|
+
when 'redis', nil
|
42
|
+
require 'resque/failure/redis'
|
43
|
+
@backend = Failure::Redis
|
44
|
+
else
|
45
|
+
raise ArgumentError, "invalid failure backend: #{FAILURE_BACKEND}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Obtain the failure queue name for a given job queue
|
50
|
+
def self.failure_queue_name(job_queue_name)
|
51
|
+
name = "#{job_queue_name}_failed"
|
52
|
+
Resque.data_store.add_failed_queue(name)
|
53
|
+
name
|
54
|
+
end
|
55
|
+
|
56
|
+
# Obtain the job queue name for a given failure queue
|
57
|
+
def self.job_queue_name(failure_queue_name)
|
58
|
+
failure_queue_name.sub(/_failed$/, '')
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns an array of all the failed queues in the system
|
62
|
+
def self.queues
|
63
|
+
backend.queues
|
37
64
|
end
|
38
65
|
|
39
66
|
# Returns the int count of how many failures we have seen.
|
40
|
-
def self.count
|
41
|
-
backend.count
|
67
|
+
def self.count(queue = nil, class_name = nil)
|
68
|
+
backend.count(queue, class_name)
|
42
69
|
end
|
43
70
|
|
44
71
|
# Returns an array of all the failures, paginated.
|
45
72
|
#
|
46
|
-
# `
|
73
|
+
# `offset` is the int of the first item in the page, `limit` is the
|
47
74
|
# number of items to return.
|
48
|
-
def self.all(
|
49
|
-
backend.all(
|
75
|
+
def self.all(offset = 0, limit = 1, queue = nil)
|
76
|
+
backend.all(offset, limit, queue)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Iterate across all failures with the given options
|
80
|
+
def self.each(offset = 0, limit = self.count, queue = nil, class_name = nil, order = 'desc', &block)
|
81
|
+
backend.each(offset, limit, queue, class_name, order, &block)
|
50
82
|
end
|
51
83
|
|
52
84
|
# The string url of the backend's web interface, if any.
|
@@ -55,42 +87,40 @@ module Resque
|
|
55
87
|
end
|
56
88
|
|
57
89
|
# Clear all failure jobs
|
58
|
-
def self.clear
|
59
|
-
backend.clear
|
90
|
+
def self.clear(queue = nil)
|
91
|
+
backend.clear(queue)
|
60
92
|
end
|
61
93
|
|
62
|
-
def self.
|
63
|
-
|
94
|
+
def self.clear_retried
|
95
|
+
each do |index, job|
|
96
|
+
remove(index) unless job['retried_at'].nil?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.requeue(id, queue = nil)
|
101
|
+
backend.requeue(id, queue)
|
64
102
|
end
|
65
103
|
|
66
|
-
def self.remove(
|
67
|
-
backend.remove(
|
104
|
+
def self.remove(id, queue = nil)
|
105
|
+
backend.remove(id, queue)
|
68
106
|
end
|
69
|
-
|
107
|
+
|
70
108
|
# Requeues all failed jobs in a specific queue.
|
71
109
|
# Queue name should be a string.
|
72
110
|
def self.requeue_queue(queue)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
111
|
+
backend.requeue_queue(queue)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Requeues all failed jobs
|
115
|
+
def self.requeue_all
|
116
|
+
backend.requeue_all
|
80
117
|
end
|
81
118
|
|
82
119
|
# Removes all failed jobs in a specific queue.
|
83
120
|
# Queue name should be a string.
|
84
121
|
def self.remove_queue(queue)
|
85
|
-
|
86
|
-
while job = Resque::Failure.all(i)
|
87
|
-
if job['queue'] == queue
|
88
|
-
# This will remove the failure from the array so do not increment the index.
|
89
|
-
Resque::Failure.remove(i)
|
90
|
-
else
|
91
|
-
i+=1
|
92
|
-
end
|
93
|
-
end
|
122
|
+
backend.remove_queue(queue)
|
94
123
|
end
|
124
|
+
|
95
125
|
end
|
96
126
|
end
|
data/lib/resque/helpers.rb
CHANGED
@@ -15,80 +15,34 @@ module Resque
|
|
15
15
|
|
16
16
|
# Direct access to the Redis instance.
|
17
17
|
def redis
|
18
|
+
# No infinite recursions, please.
|
19
|
+
# Some external libraries depend on Resque::Helpers being mixed into
|
20
|
+
# Resque, but this method causes recursions. If we have a super method,
|
21
|
+
# assume it is canonical. (see #1150)
|
22
|
+
return super if defined?(super)
|
23
|
+
|
18
24
|
Resque.redis
|
19
25
|
end
|
20
26
|
|
21
27
|
# Given a Ruby object, returns a string suitable for storage in a
|
22
28
|
# queue.
|
23
29
|
def encode(object)
|
24
|
-
|
25
|
-
MultiJson.dump object
|
26
|
-
else
|
27
|
-
MultiJson.encode object
|
28
|
-
end
|
29
|
-
|
30
|
+
Resque.encode(object)
|
30
31
|
end
|
31
32
|
|
32
33
|
# Given a string, returns a Ruby object.
|
33
34
|
def decode(object)
|
34
|
-
|
35
|
-
|
36
|
-
begin
|
37
|
-
if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
38
|
-
MultiJson.load object
|
39
|
-
else
|
40
|
-
MultiJson.decode object
|
41
|
-
end
|
42
|
-
rescue ::MultiJson::DecodeError => e
|
43
|
-
raise DecodeException, e.message, e.backtrace
|
44
|
-
end
|
35
|
+
Resque.decode(object)
|
45
36
|
end
|
46
37
|
|
47
38
|
# Given a word with dashes, returns a camel cased version of it.
|
48
|
-
#
|
49
|
-
# classify('job-name') # => 'JobName'
|
50
39
|
def classify(dashed_word)
|
51
|
-
|
40
|
+
Resque.classify(dashed_word)
|
52
41
|
end
|
53
42
|
|
54
|
-
# Tries to find a constant with the name specified in the argument string
|
55
|
-
#
|
56
|
-
# constantize("Module") # => Module
|
57
|
-
# constantize("Test::Unit") # => Test::Unit
|
58
|
-
#
|
59
|
-
# The name is assumed to be the one of a top-level constant, no matter
|
60
|
-
# whether it starts with "::" or not. No lexical context is taken into
|
61
|
-
# account:
|
62
|
-
#
|
63
|
-
# C = 'outside'
|
64
|
-
# module M
|
65
|
-
# C = 'inside'
|
66
|
-
# C # => 'inside'
|
67
|
-
# constantize("C") # => 'outside', same as ::C
|
68
|
-
# end
|
69
|
-
#
|
70
|
-
# NameError is raised when the constant is unknown.
|
43
|
+
# Tries to find a constant with the name specified in the argument string
|
71
44
|
def constantize(camel_cased_word)
|
72
|
-
camel_cased_word
|
73
|
-
|
74
|
-
if camel_cased_word.include?('-')
|
75
|
-
camel_cased_word = classify(camel_cased_word)
|
76
|
-
end
|
77
|
-
|
78
|
-
names = camel_cased_word.split('::')
|
79
|
-
names.shift if names.empty? || names.first.empty?
|
80
|
-
|
81
|
-
constant = Object
|
82
|
-
names.each do |name|
|
83
|
-
args = Module.method(:const_get).arity != 1 ? [false] : []
|
84
|
-
|
85
|
-
if constant.const_defined?(name, *args)
|
86
|
-
constant = constant.const_get(name)
|
87
|
-
else
|
88
|
-
constant = constant.const_missing(name)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
constant
|
45
|
+
Resque.constantize(camel_cased_word)
|
92
46
|
end
|
93
47
|
end
|
94
48
|
end
|
data/lib/resque/job.rb
CHANGED
@@ -14,6 +14,50 @@ module Resque
|
|
14
14
|
class Job
|
15
15
|
include Helpers
|
16
16
|
extend Helpers
|
17
|
+
def redis
|
18
|
+
Resque.redis
|
19
|
+
end
|
20
|
+
alias :data_store :redis
|
21
|
+
|
22
|
+
def self.redis
|
23
|
+
Resque.redis
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.data_store
|
27
|
+
self.redis
|
28
|
+
end
|
29
|
+
|
30
|
+
# Given a Ruby object, returns a string suitable for storage in a
|
31
|
+
# queue.
|
32
|
+
def encode(object)
|
33
|
+
Resque.encode(object)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Given a string, returns a Ruby object.
|
37
|
+
def decode(object)
|
38
|
+
Resque.decode(object)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Given a Ruby object, returns a string suitable for storage in a
|
42
|
+
# queue.
|
43
|
+
def self.encode(object)
|
44
|
+
Resque.encode(object)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Given a string, returns a Ruby object.
|
48
|
+
def self.decode(object)
|
49
|
+
Resque.decode(object)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Given a word with dashes, returns a camel cased version of it.
|
53
|
+
def classify(dashed_word)
|
54
|
+
Resque.classify(dashed_word)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Tries to find a constant with the name specified in the argument string
|
58
|
+
def constantize(camel_cased_word)
|
59
|
+
Resque.constantize(camel_cased_word)
|
60
|
+
end
|
17
61
|
|
18
62
|
# Raise Resque::Job::DontPerform from a before_perform hook to
|
19
63
|
# abort the job.
|
@@ -78,17 +122,16 @@ module Resque
|
|
78
122
|
# a Ruby array before processing.
|
79
123
|
def self.destroy(queue, klass, *args)
|
80
124
|
klass = klass.to_s
|
81
|
-
queue = "queue:#{queue}"
|
82
125
|
destroyed = 0
|
83
126
|
|
84
127
|
if args.empty?
|
85
|
-
|
128
|
+
data_store.everything_in_queue(queue).each do |string|
|
86
129
|
if decode(string)['class'] == klass
|
87
|
-
destroyed +=
|
130
|
+
destroyed += data_store.remove_from_queue(queue,string).to_i
|
88
131
|
end
|
89
132
|
end
|
90
133
|
else
|
91
|
-
destroyed +=
|
134
|
+
destroyed += data_store.remove_from_queue(queue, encode(:class => klass, :args => args))
|
92
135
|
end
|
93
136
|
|
94
137
|
destroyed
|
@@ -111,7 +154,7 @@ module Resque
|
|
111
154
|
|
112
155
|
begin
|
113
156
|
# Execute before_perform hook. Abort the job gracefully if
|
114
|
-
# Resque::DontPerform is raised.
|
157
|
+
# Resque::Job::DontPerform is raised.
|
115
158
|
begin
|
116
159
|
before_hooks.each do |hook|
|
117
160
|
job.send(hook, *job_args)
|
@@ -166,6 +209,19 @@ module Resque
|
|
166
209
|
@payload_class ||= constantize(@payload['class'])
|
167
210
|
end
|
168
211
|
|
212
|
+
# Returns the payload class as a string without raising NameError
|
213
|
+
def payload_class_name
|
214
|
+
payload_class.to_s
|
215
|
+
rescue NameError
|
216
|
+
'No Name'
|
217
|
+
end
|
218
|
+
|
219
|
+
def has_payload_class?
|
220
|
+
payload_class != Object
|
221
|
+
rescue NameError
|
222
|
+
false
|
223
|
+
end
|
224
|
+
|
169
225
|
# Returns an array of args represented in this job's payload.
|
170
226
|
def args
|
171
227
|
@payload['args']
|
@@ -174,12 +230,17 @@ module Resque
|
|
174
230
|
# Given an exception object, hands off the needed parameters to
|
175
231
|
# the Failure module.
|
176
232
|
def fail(exception)
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
233
|
+
begin
|
234
|
+
run_failure_hooks(exception)
|
235
|
+
rescue Exception => e
|
236
|
+
raise e
|
237
|
+
ensure
|
238
|
+
Failure.create \
|
239
|
+
:payload => payload,
|
240
|
+
:exception => exception,
|
241
|
+
:worker => worker,
|
242
|
+
:queue => queue
|
243
|
+
end
|
183
244
|
end
|
184
245
|
|
185
246
|
# Creates an identical job, essentially placing this job back on
|
@@ -220,7 +281,13 @@ module Resque
|
|
220
281
|
def run_failure_hooks(exception)
|
221
282
|
begin
|
222
283
|
job_args = args || []
|
223
|
-
|
284
|
+
if has_payload_class?
|
285
|
+
failure_hooks.each { |hook| payload_class.send(hook, exception, *job_args) } unless @failure_hooks_ran
|
286
|
+
end
|
287
|
+
rescue Exception => e
|
288
|
+
error_message = "Additional error (#{e.class}: #{e}) occurred in running failure hooks for job #{inspect}\n" \
|
289
|
+
"Original error that caused job failure was #{e.class}: #{exception.class}: #{exception.message}"
|
290
|
+
raise RuntimeError.new(error_message)
|
224
291
|
ensure
|
225
292
|
@failure_hooks_ran = true
|
226
293
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Resque
|
2
|
+
# Include this module in classes you wish to have logging facilities
|
3
|
+
module Logging
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# Thunk to the logger's own log method (if configured)
|
7
|
+
def self.log(severity, message)
|
8
|
+
Resque.logger.__send__(severity, message) if Resque.logger
|
9
|
+
end
|
10
|
+
|
11
|
+
# Log level aliases
|
12
|
+
def debug(message); Logging.log :debug, message; end
|
13
|
+
def info(message); Logging.log :info, message; end
|
14
|
+
def warn(message); Logging.log :warn, message; end
|
15
|
+
def error(message); Logging.log :error, message; end
|
16
|
+
def fatal(message); Logging.log :fatal, message; end
|
17
|
+
end
|
18
|
+
end
|