Class: Hutch::ErrorHandlers::MaxRetry
- Inherits:
-
Object
- Object
- Hutch::ErrorHandlers::MaxRetry
- Includes:
- Logging
- Defined in:
- lib/hutch/error_handlers/max_retry.rb
Overview
When reach the Max Attempts, republish this message to RabbitMQ, And persisted the properties to tell RabbitMQ the ‘x-dead.count`
Instance Method Summary collapse
- #failure_count(headers, consumer) ⇒ Object
-
#handle(properties, payload, consumer, ex) ⇒ Object
properties.headers example: { “x-death”: [ { “count”: 7, “exchange”: “hutch.topic”, “queue”: “retry_queue”, “reason”: “expired”, “routing-keys”: [ “plan” ], “time”: “2017-05-13 23:37:15 0800” }, { “count”: 7, “exchange”: “hutch”, “original-expiration”: “3000”, “queue”: “plan_consumer”, “reason”: “rejected”, “routing-keys”: [ “plan” ], “time”: “2017-05-13 23:37:05 0800” } ] }.
-
#retry_delay(executes) ⇒ Object
becareful with the RabbitMQ fixed delay level, this retry_dealy seconds will fit to one fixed delay level.
Instance Method Details
#failure_count(headers, consumer) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/hutch/error_handlers/max_retry.rb', line 61 def failure_count(headers, consumer) if headers.nil? || headers['x-death'].nil? 0 else x_death_array = headers['x-death'].select do |x_death| # http://ruby-doc.org/stdlib-2.2.3/libdoc/set/rdoc/Set.html#method-i-intersect-3F (x_death['routing-keys'].presence || []).to_set.intersect?(consumer.routing_keys) end if x_death_array.count > 0 && x_death_array.first['count'] # Newer versions of RabbitMQ return headers with a count key x_death_array.inject(0) { |sum, x_death| sum + x_death['count'] } else # Older versions return a separate x-death header for each failure x_death_array.count end end end |
#handle(properties, payload, consumer, ex) ⇒ Object
properties.headers example: {
"x-death": [
{
"count": 7,
"exchange": "hutch.topic",
"queue": "retry_queue",
"reason": "expired",
"routing-keys": [
"plan"
],
"time": "2017-05-13 23:37:15 +0800"
},
{
"count": 7,
"exchange": "hutch",
"original-expiration": "3000",
"queue": "plan_consumer",
"reason": "rejected",
"routing-keys": [
"plan"
],
"time": "2017-05-13 23:37:05 +0800"
}
]
}
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/hutch/error_handlers/max_retry.rb', line 38 def handle(properties, payload, consumer, ex) unless consumer.ancestors.include?(Hutch::Enqueue) logger.warn("Consumer: #{consumer} is not include Hutch::Enqueue can`t use #enqueue_in`") return false end prop_headers = properties[:headers] || {} attempts = failure_count(prop_headers, consumer) + 1 if attempts <= consumer.max_attempts logger.debug("retrying, count=#{attempts}, headers:#{prop_headers}") # execute_times = attempts - 1 consumer.enqueue_in(retry_delay(attempts - 1), MultiJson.decode(payload), { headers: prop_headers }) else logger.debug("failing, retry_count=#{attempts}, ex:#{ex}") end end |
#retry_delay(executes) ⇒ Object
becareful with the RabbitMQ fixed delay level, this retry_dealy seconds will fit to one fixed delay level. so the max delay time is limit to 3 hours(10800s, error times 11: 14643)
57 58 59 |
# File 'lib/hutch/error_handlers/max_retry.rb', line 57 def retry_delay(executes) (executes**4) + 2 end |