Retries

The :retries plugin allows requests to be retried when errors happen.

:max_retries

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)

:retry_after

In case you need to wait before retrying again, you can use the :retry_after option, which receives the time to wait in seconds (or milliseconds, i.e. 0.5 == 500ms) after which you retry, or alternatively, a callable which receives the last failed request and returns the time 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 })

:retry_jitter

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

:retry_on

Request only get retried in a few situations.

In order for you to change the conditions under which a retry happens, 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...

:retry_change_requests

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!

Request

The request object has a method, #retries, which returns the number of times the request has been retried.

Errors

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