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.
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