Class: Faraday::Request::Retry
- Inherits:
-
Middleware
- Object
- Middleware
- Faraday::Request::Retry
- Defined in:
- lib/faraday/request/retry.rb
Overview
Catches exceptions and retries each request a limited number of times.
By default, it retries 2 times and handles only timeout exceptions. It can be configured with an arbitrary number of retries, a list of exceptions to handle, a retry interval, a percentage of randomness to add to the retry interval, and a backoff factor.
Examples
Faraday.new do |conn|
conn.request :retry, max: 2, interval: 0.05,
interval_randomness: 0.5, backoff_factor: 2,
exceptions: [CustomException, 'Timeout::Error']
conn.adapter ...
end
This example will result in a first interval that is random between 0.05 and 0.075 and a second interval that is random between 0.1 and 0.15
Defined Under Namespace
Classes: Options
Constant Summary collapse
- IDEMPOTENT_METHODS =
[:delete, :get, :head, :options, :put]
Instance Method Summary collapse
-
#build_exception_matcher(exceptions) ⇒ Object
Private: construct an exception matcher object.
- #call(env) ⇒ Object
-
#initialize(app, options = nil) ⇒ Retry
constructor
Public: Initialize middleware.
- #sleep_amount(retries) ⇒ Object
Methods inherited from Middleware
dependency, inherited, loaded?, new
Methods included from MiddlewareRegistry
#fetch_middleware, #load_middleware, #lookup_middleware, #middleware_mutex, #register_middleware
Constructor Details
#initialize(app, options = nil) ⇒ Retry
Public: Initialize middleware
Options: max - Maximum number of retries (default: 2) interval - Pause in seconds between retries (default: 0) interval_randomness - The maximum random interval amount expressed
as a float between 0 and 1 to use in addition to the
interval. (default: 0)
max_interval - An upper limit for the interval (default: Float::MAX) backoff_factor - The amount to multiple each successive retry’s
interval amount by in order to provide backoff
(default: 1)
exceptions - The list of exceptions to handle. Exceptions can be
given as Class, Module, or String. (default:
[Errno::ETIMEDOUT, Timeout::Error,
Error::TimeoutError])
methods - A list of HTTP methods to retry without calling retry_if. Pass
an empty Array to call retry_if for all exceptions.
(defaults to the idempotent HTTP methods in IDEMPOTENT_METHODS)
retry_if - block that will receive the env object and the exception raised
and should decide if the code should retry still the action or
not independent of the retry count. This would be useful
if the exception produced is non-recoverable or if the
the HTTP method called is not idempotent.
(defaults to return false)
97 98 99 100 101 |
# File 'lib/faraday/request/retry.rb', line 97 def initialize(app, = nil) super(app) @options = Options.from() @errmatch = build_exception_matcher(@options.exceptions) end |
Instance Method Details
#build_exception_matcher(exceptions) ⇒ Object
Private: construct an exception matcher object.
An exception matcher for the rescue clause can usually be any object that responds to ‘===`, but for Ruby 1.8 it has to be a Class or Module.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/faraday/request/retry.rb', line 132 def build_exception_matcher(exceptions) matcher = Module.new (class << matcher; self; end).class_eval do define_method(:===) do |error| exceptions.any? do |ex| if ex.is_a? Module error.is_a? ex else error.class.to_s == ex.to_s end end end end matcher end |
#call(env) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/faraday/request/retry.rb', line 111 def call(env) retries = @options.max request_body = env[:body] begin env[:body] = request_body # after failure env[:body] is set to the response body @app.call(env) rescue @errmatch => exception if retries > 0 && retry_request?(env, exception) retries -= 1 rewind_files(request_body) sleep sleep_amount(retries + 1) retry end raise end end |
#sleep_amount(retries) ⇒ Object
103 104 105 106 107 108 109 |
# File 'lib/faraday/request/retry.rb', line 103 def sleep_amount(retries) retry_index = @options.max - retries current_interval = @options.interval * (@options.backoff_factor ** retry_index) current_interval = [current_interval, @options.max_interval].min random_interval = rand * @options.interval_randomness.to_f * @options.interval current_interval + random_interval end |