class Hutch::ErrorHandlers::MaxRetry
When reach the Max Attempts, republish this message to RabbitMQ, And persisted the properties to tell RabbitMQ the `x-dead.count`
Public Instance Methods
failure_count(headers, consumer)
click to toggle source
# 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)
click to toggle source
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" } ]
}
# 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)
click to toggle source
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)
# File lib/hutch/error_handlers/max_retry.rb, line 57 def retry_delay(executes) (executes ** 4) + 2 end