Note: Introduced in 0.1.0
.
The retries
plugin allows requests to be retried when certain errors happen.
You can set how many times a request can be retried by passing the max_retries
option (or method), which by default is 3 times:
session = HTTPX.plugin(:retries)
session.max_retries(10).get(URL)
# or
session.get(URL, max_retries: 10)
In case you need to wait before retrying again, you can use the retry_after
option, which receives the number of seconds after which you retry, or alternatively, a callable which receives the last failed request and returns the number of seconds to wait (in handy if you want to do exponential backoff):
session = HTTPX.plugin(:retries, retry_after: 2)
session.get(URL, retry_after: 3)
# or, for own exponential back-off
retries = 0
session.get(URL, retry_after: ->(*) { (retries += 1) * 2 })
(since v0.18.0
)
When using the :retry_after
option, some jitter will be applied to it, thereby not making the retry interval necessarily exact, but applying enough “randomness” in order to make it more resilient to “thundering herd” events.
If you would like to insert your own “jitter” calculation algorithm, you can use this option and pass it a proc:
session = HTTPX.plugin(:retries, retry_after: 2, retry_jitter: ->(interval) { interval + rand }) # ...
(In case you would like to turn off jitter calculation altogether, you can set the following env var: HTTPX_NO_JITTER=1
).
In order for you to decide on when to retry, you can use the retry_on
option, a callable which receives the failed response, to determine whether the request should be retried.
session = HTTPX.plugin(:retries, retry_on: ->(res) { res.error.is_a?(TimeoutError)})
session.get(URL, body: "body") # only retries if it times out...
Attention! The retry_on
callback accepts request and response only since v0.10.0. If you’re using a previous version, the callback only accepts the response.
By default, only idempotent requests are retried (GET
, PUT
…). If you also want, p. ex. POST
requests to be retried on, you can pass this option:
session = HTTPX.plugin(:retries)
session.post(URL, body: "body", retry_on: ->(res) { res.error.is_a?(TimeoutError)} ) # won't retry, because it's a POST request
# instead
session = HTTPX.plugin(:retries, retry_change_requests: true)
session.post(URL, body: "body", retry_on: ->(res) { res.error.is_a?(TimeoutError)} ) # now it can be retried!
The request object has a method, #retries
, which returns the number of times the request has been retried.
Unless you’re using the retry_on
option, requests will be retried only when connection type errors happen, like network errors (IOError
…), TLS errors (OpenSSL::SSL::SSLError
…) or timeout errors. A 500 HTTP response will, therefore, be considered a valid response.
Next: Cookies