resque 1.23.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY.md +271 -0
  3. data/README.markdown +454 -484
  4. data/Rakefile +4 -17
  5. data/bin/resque-web +10 -22
  6. data/lib/resque/data_store.rb +335 -0
  7. data/lib/resque/errors.rb +15 -1
  8. data/lib/resque/failure/airbrake.rb +32 -4
  9. data/lib/resque/failure/base.rb +16 -7
  10. data/lib/resque/failure/multiple.rb +26 -8
  11. data/lib/resque/failure/redis.rb +92 -15
  12. data/lib/resque/failure/redis_multi_queue.rb +104 -0
  13. data/lib/resque/failure.rb +62 -32
  14. data/lib/resque/helpers.rb +11 -57
  15. data/lib/resque/job.rb +79 -12
  16. data/lib/resque/log_formatters/quiet_formatter.rb +7 -0
  17. data/lib/resque/log_formatters/verbose_formatter.rb +7 -0
  18. data/lib/resque/log_formatters/very_verbose_formatter.rb +8 -0
  19. data/lib/resque/logging.rb +18 -0
  20. data/lib/resque/plugin.rb +22 -10
  21. data/lib/resque/railtie.rb +10 -0
  22. data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
  23. data/lib/resque/server/public/jquery.relatize_date.js +4 -4
  24. data/lib/resque/server/public/main.js +3 -0
  25. data/lib/resque/server/public/ranger.js +16 -8
  26. data/lib/resque/server/public/style.css +13 -8
  27. data/lib/resque/server/views/error.erb +1 -1
  28. data/lib/resque/server/views/failed.erb +27 -59
  29. data/lib/resque/server/views/failed_job.erb +50 -0
  30. data/lib/resque/server/views/failed_queues_overview.erb +24 -0
  31. data/lib/resque/server/views/job_class.erb +8 -0
  32. data/lib/resque/server/views/key_sets.erb +2 -4
  33. data/lib/resque/server/views/key_string.erb +1 -1
  34. data/lib/resque/server/views/layout.erb +7 -6
  35. data/lib/resque/server/views/next_more.erb +22 -10
  36. data/lib/resque/server/views/processing.erb +2 -0
  37. data/lib/resque/server/views/queues.erb +22 -13
  38. data/lib/resque/server/views/stats.erb +5 -5
  39. data/lib/resque/server/views/workers.erb +4 -4
  40. data/lib/resque/server/views/working.erb +10 -11
  41. data/lib/resque/server.rb +51 -108
  42. data/lib/resque/server_helper.rb +185 -0
  43. data/lib/resque/stat.rb +19 -7
  44. data/lib/resque/tasks.rb +26 -25
  45. data/lib/resque/thread_signal.rb +24 -0
  46. data/lib/resque/vendor/utf8_util.rb +2 -8
  47. data/lib/resque/version.rb +1 -1
  48. data/lib/resque/web_runner.rb +374 -0
  49. data/lib/resque/worker.rb +487 -163
  50. data/lib/resque.rb +332 -52
  51. data/lib/tasks/redis.rake +11 -11
  52. metadata +169 -149
  53. data/lib/resque/failure/hoptoad.rb +0 -33
  54. data/lib/resque/failure/thoughtbot.rb +0 -33
  55. data/lib/resque/server/public/jquery-1.3.2.min.js +0 -19
  56. data/lib/resque/server/test_helper.rb +0 -19
  57. data/lib/resque/vendor/utf8_util/utf8_util_18.rb +0 -91
  58. data/lib/resque/vendor/utf8_util/utf8_util_19.rb +0 -5
  59. data/test/airbrake_test.rb +0 -27
  60. data/test/hoptoad_test.rb +0 -26
  61. data/test/job_hooks_test.rb +0 -464
  62. data/test/job_plugins_test.rb +0 -230
  63. data/test/plugin_test.rb +0 -116
  64. data/test/redis-test-cluster.conf +0 -115
  65. data/test/redis-test.conf +0 -115
  66. data/test/resque-web_test.rb +0 -59
  67. data/test/resque_failure_redis_test.rb +0 -19
  68. data/test/resque_test.rb +0 -278
  69. data/test/test_helper.rb +0 -178
  70. data/test/worker_test.rb +0 -657
@@ -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
- Resque.redis.rpush(:failed, data)
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.count
21
- Resque.redis.llen(:failed).to_i
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.all(start = 0, count = 1)
25
- Resque.list_range(:failed, start, count)
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
- Resque.redis.del(:failed)
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(index)
33
- item = all(index)
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
- Resque.redis.lset(:failed, index, Resque.encode(item))
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(index)
40
- id = rand(0xffffff)
41
- Resque.redis.lset(:failed, index, id)
42
- Resque.redis.lrem(:failed, 1, id)
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
@@ -22,31 +22,63 @@ module Resque
22
22
  # `Resque::Failure::Base`.
23
23
  #
24
24
  # Example use:
25
- # require 'resque/failure/hoptoad'
26
- # Resque::Failure.backend = Resque::Failure::Hoptoad
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
- require 'resque/failure/redis'
36
- @backend = Failure::Redis
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
- # `start` is the int of the first item in the page, `count` is the
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(start = 0, count = 1)
49
- backend.all(start, count)
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.requeue(index)
63
- backend.requeue(index)
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(index)
67
- backend.remove(index)
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
- i=0
74
- while job = Resque::Failure.all(i)
75
- if job['queue'] == queue
76
- Resque::Failure.requeue(i)
77
- end
78
- i+=1
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
- i=0
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
@@ -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
- if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
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
- return unless object
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
- dashed_word.split('-').each { |part| part[0] = part[0].chr.upcase }.join
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 = camel_cased_word.to_s
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
- redis.lrange(queue, 0, -1).each do |string|
128
+ data_store.everything_in_queue(queue).each do |string|
86
129
  if decode(string)['class'] == klass
87
- destroyed += redis.lrem(queue, 0, string).to_i
130
+ destroyed += data_store.remove_from_queue(queue,string).to_i
88
131
  end
89
132
  end
90
133
  else
91
- destroyed += redis.lrem(queue, 0, encode(:class => klass, :args => args))
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
- run_failure_hooks(exception)
178
- Failure.create \
179
- :payload => payload,
180
- :exception => exception,
181
- :worker => worker,
182
- :queue => queue
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
- failure_hooks.each { |hook| payload_class.send(hook, exception, *job_args) } unless @failure_hooks_ran
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,7 @@
1
+ module Resque
2
+ class QuietFormatter
3
+ def call(serverity, datetime, progname, msg)
4
+ ""
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Resque
2
+ class VerboseFormatter
3
+ def call(serverity, datetime, progname, msg)
4
+ "*** #{msg}\n"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Resque
2
+ class VeryVerboseFormatter
3
+ def call(serverity, datetime, progname, msg)
4
+ time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
5
+ "** [#{time}] #$$: #{msg}\n"
6
+ end
7
+ end
8
+ 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