faraday-retry 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +33 -6
- data/lib/faraday/retry/middleware.rb +24 -26
- data/lib/faraday/retry/retryable.rb +44 -0
- data/lib/faraday/retry/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af805c058f1e08fba4ab4c53587f88906f086f06bda02dd4daf578123d6aa79f
|
4
|
+
data.tar.gz: 714eeaadf0d8021d7c33f86ece4dda66366fcc6525e8bf395c3e71591d0a8bc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6de30437afefef5b6887a0c7b2e72615775b63a92aaee63c37672631d9e09011b0b46fa9c208e6ca280d55ace287e12c9077ed18107968bc5593255cd028b6c1
|
7
|
+
data.tar.gz: dc0e7f4b11e714addd9a11426cc5071eb2245ea8f5cb24a38e7f63ee50030df81b14380912b4f0b786f9bfa53dfeccbc16f802337638054d7e36ad56be667f3f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Unreleased
|
4
|
+
|
5
|
+
_nothing yet_
|
6
|
+
|
7
|
+
## v2.2.1 (2024-04-15)
|
8
|
+
|
9
|
+
* Avoid deprecation warning about ::UploadIO constant when used without faraday-multipart gem [PR #37](https://github.com/lostisland/faraday-retry/pull/37) [@iMacTia]
|
10
|
+
* Documentation update [PR #30](https://github.com/lostisland/faraday-retry/pull/30) [@olleolleolle]
|
11
|
+
* Documentation update [PR #32](https://github.com/lostisland/faraday-retry/pull/32) Thanks, [@Drowze]!
|
12
|
+
|
3
13
|
## v2.2.0 (2023-06-01)
|
4
14
|
|
5
15
|
* Support new `header_parser_block` option. [PR #28](https://github.com/lostisland/faraday-retry/pull/28). Thanks, [@zavan]!
|
@@ -34,3 +44,6 @@ This release consists of the same middleware that was previously bundled with Fa
|
|
34
44
|
[@maxprokopiev]: https://github.com/maxprokopiev
|
35
45
|
[@brookemckim]: https://github.com/brookemckim
|
36
46
|
[@zavan]: https://github.com/zavan
|
47
|
+
[@Drowze]: https://github.com/Drowze
|
48
|
+
[@olleolleolle]: https://github.com/olleolleolle
|
49
|
+
[@iMacTia]: https://github.com/iMacTia
|
data/README.md
CHANGED
@@ -75,7 +75,7 @@ retry_options = {
|
|
75
75
|
#### Specify which exceptions should trigger a retry
|
76
76
|
|
77
77
|
You can provide an `exceptions` option with a list of exceptions that will replace
|
78
|
-
the default
|
78
|
+
the default exceptions: `Errno::ETIMEDOUT`, `Timeout::Error`, `Faraday::TimeoutError`, `Faraday::Error::RetriableResponse`.
|
79
79
|
This can be particularly useful when combined with the [RaiseError][raise_error] middleware.
|
80
80
|
|
81
81
|
```ruby
|
@@ -84,6 +84,14 @@ retry_options = {
|
|
84
84
|
}
|
85
85
|
```
|
86
86
|
|
87
|
+
If you want to inherit default exceptions, do it this way.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
retry_options = {
|
91
|
+
exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Faraday::ResourceNotFound, Faraday::UnauthorizedError]
|
92
|
+
}
|
93
|
+
```
|
94
|
+
|
87
95
|
#### Specify on which response statuses to retry
|
88
96
|
|
89
97
|
By default the `Retry` middleware will only retry the request if one of the expected exceptions arise.
|
@@ -141,13 +149,11 @@ retry_options = {
|
|
141
149
|
|
142
150
|
### Call a block on every retry
|
143
151
|
|
144
|
-
You can specify a proc object through the `retry_block` option that will be called before every
|
145
|
-
|
146
|
-
|
152
|
+
You can specify a proc object through the `retry_block` option that will be called before every retry.
|
153
|
+
There are many different applications for this feature, ranging from instrumentation to monitoring.
|
147
154
|
|
148
155
|
The block is passed keyword arguments with contextual information: Request environment, middleware options, current number of retries, exception, and amount of time we will wait before retrying. (retry_block is called before the wait time happens)
|
149
156
|
|
150
|
-
|
151
157
|
For example, you might want to keep track of the response statuses:
|
152
158
|
|
153
159
|
```ruby
|
@@ -157,6 +163,27 @@ retry_options = {
|
|
157
163
|
}
|
158
164
|
```
|
159
165
|
|
166
|
+
### Call a block after retries have been exhausted
|
167
|
+
|
168
|
+
You can specify a lambda object through the `exhausted_retries_block` option that will be called after all retries are exhausted.
|
169
|
+
This block will be called once.
|
170
|
+
|
171
|
+
The block is passed keyword arguments with contextual information and passed your data:
|
172
|
+
* Request environment,
|
173
|
+
* exception,
|
174
|
+
* middleware options
|
175
|
+
* and your data.
|
176
|
+
|
177
|
+
In a lambda you can pass any logic for further work.
|
178
|
+
|
179
|
+
For example, you might want to update user by request query.
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
retry_options = {
|
183
|
+
exhausted_retries_block: -> (user_id:, env:, exception:, options:) { User.find_by!(id: user_id).do_admin! }
|
184
|
+
}
|
185
|
+
```
|
186
|
+
|
160
187
|
## Development
|
161
188
|
|
162
189
|
After checking out the repo, run `bin/setup` to install dependencies.
|
@@ -177,4 +204,4 @@ Bug reports and pull requests are welcome on [GitHub](https://github.com/lostisl
|
|
177
204
|
|
178
205
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
179
206
|
|
180
|
-
[raise_error]: https://lostisland.github.io/faraday
|
207
|
+
[raise_error]: https://lostisland.github.io/faraday/#/middleware/included/raising-errors
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'retryable'
|
4
|
+
|
3
5
|
module Faraday
|
4
6
|
module Retry
|
5
7
|
# This class provides the main implementation for your middleware.
|
@@ -15,6 +17,8 @@ module Faraday
|
|
15
17
|
# (see "retry" middleware: https://github.com/lostisland/faraday/blob/main/lib/faraday/request/retry.rb#L142).
|
16
18
|
# IMPORTANT: Remember to call `@app.call(env)` or `super` to not interrupt the middleware chain!
|
17
19
|
class Middleware < Faraday::Middleware
|
20
|
+
include Retryable
|
21
|
+
|
18
22
|
DEFAULT_EXCEPTIONS = [
|
19
23
|
Errno::ETIMEDOUT, 'Timeout::Error',
|
20
24
|
Faraday::TimeoutError, Faraday::RetriableResponse
|
@@ -27,7 +31,8 @@ module Faraday
|
|
27
31
|
:backoff_factor, :exceptions,
|
28
32
|
:methods, :retry_if, :retry_block,
|
29
33
|
:retry_statuses, :rate_limit_retry_header,
|
30
|
-
:rate_limit_reset_header, :header_parser_block
|
34
|
+
:rate_limit_reset_header, :header_parser_block,
|
35
|
+
:exhausted_retries_block)
|
31
36
|
|
32
37
|
DEFAULT_CHECK = ->(_env, _exception) { false }
|
33
38
|
|
@@ -78,6 +83,10 @@ module Faraday
|
|
78
83
|
def retry_statuses
|
79
84
|
Array(self[:retry_statuses] ||= [])
|
80
85
|
end
|
86
|
+
|
87
|
+
def exhausted_retries_block
|
88
|
+
self[:exhausted_retries_block] ||= proc {}
|
89
|
+
end
|
81
90
|
end
|
82
91
|
|
83
92
|
# @param app [#call]
|
@@ -95,8 +104,8 @@ module Faraday
|
|
95
104
|
# 'Timeout::Error', Faraday::TimeoutError, Faraday::RetriableResponse])
|
96
105
|
# The list of exceptions to handle. Exceptions can be given as
|
97
106
|
# Class, Module, or String.
|
98
|
-
# @option options [Array] :methods (the idempotent HTTP methods
|
99
|
-
# in IDEMPOTENT_METHODS) A list of HTTP methods to retry without
|
107
|
+
# @option options [Array<Symbol>] :methods (the idempotent HTTP methods
|
108
|
+
# in IDEMPOTENT_METHODS) A list of HTTP methods, as symbols, to retry without
|
100
109
|
# calling retry_if. Pass an empty Array to call retry_if
|
101
110
|
# for all exceptions.
|
102
111
|
# @option options [Block] :retry_if (false) block that will receive
|
@@ -124,6 +133,13 @@ module Faraday
|
|
124
133
|
# the the value of the retry header and should return the number of
|
125
134
|
# seconds to wait before retrying the request. This is useful if the
|
126
135
|
# value of the header is not a number of seconds or a RFC 2822 formatted date.
|
136
|
+
# @option options [Block] :exhausted_retries_block block will receive
|
137
|
+
# when all attempts are exhausted. The block will be yielded keyword arguments:
|
138
|
+
# * env [Faraday::Env]: Request environment
|
139
|
+
# * exception [Exception]: exception that triggered the retry,
|
140
|
+
# will be the synthetic `Faraday::RetriableResponse` if the
|
141
|
+
# retry was triggered by something other than an exception.
|
142
|
+
# * options [Faraday::Options]: middleware options
|
127
143
|
def initialize(app, options = nil)
|
128
144
|
super(app)
|
129
145
|
@options = Options.from(options)
|
@@ -147,32 +163,14 @@ module Faraday
|
|
147
163
|
def call(env)
|
148
164
|
retries = @options.max
|
149
165
|
request_body = env[:body]
|
150
|
-
|
166
|
+
|
167
|
+
with_retries(env: env, options: @options, retries: retries, body: request_body, errmatch: @errmatch) do
|
151
168
|
# after failure env[:body] is set to the response body
|
152
169
|
env[:body] = request_body
|
170
|
+
|
153
171
|
@app.call(env).tap do |resp|
|
154
172
|
raise Faraday::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
|
155
173
|
end
|
156
|
-
rescue @errmatch => e
|
157
|
-
if retries.positive? && retry_request?(env, e)
|
158
|
-
retries -= 1
|
159
|
-
rewind_files(request_body)
|
160
|
-
if (sleep_amount = calculate_sleep_amount(retries + 1, env))
|
161
|
-
@options.retry_block.call(
|
162
|
-
env: env,
|
163
|
-
options: @options,
|
164
|
-
retry_count: @options.max - (retries + 1),
|
165
|
-
exception: e,
|
166
|
-
will_retry_in: sleep_amount
|
167
|
-
)
|
168
|
-
sleep sleep_amount
|
169
|
-
retry
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
raise unless e.is_a?(Faraday::RetriableResponse)
|
174
|
-
|
175
|
-
e.response
|
176
174
|
end
|
177
175
|
end
|
178
176
|
|
@@ -209,11 +207,11 @@ module Faraday
|
|
209
207
|
end
|
210
208
|
|
211
209
|
def rewind_files(body)
|
212
|
-
return unless defined?(UploadIO)
|
210
|
+
return unless defined?(Faraday::UploadIO)
|
213
211
|
return unless body.is_a?(Hash)
|
214
212
|
|
215
213
|
body.each do |_, value|
|
216
|
-
value.rewind if value.is_a?(UploadIO)
|
214
|
+
value.rewind if value.is_a?(Faraday::UploadIO)
|
217
215
|
end
|
218
216
|
end
|
219
217
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Adds the ability to retry a request based on settings and errors that have occurred.
|
4
|
+
module Retryable
|
5
|
+
def with_retries(env:, options:, retries:, body:, errmatch:)
|
6
|
+
yield
|
7
|
+
rescue errmatch => e
|
8
|
+
exhausted_retries(options, env, e) if retries_zero?(retries, env, e)
|
9
|
+
|
10
|
+
if retries.positive? && retry_request?(env, e)
|
11
|
+
retries -= 1
|
12
|
+
rewind_files(body)
|
13
|
+
if (sleep_amount = calculate_sleep_amount(retries + 1, env))
|
14
|
+
options.retry_block.call(
|
15
|
+
env: env,
|
16
|
+
options: options,
|
17
|
+
retry_count: options.max - (retries + 1),
|
18
|
+
exception: e,
|
19
|
+
will_retry_in: sleep_amount
|
20
|
+
)
|
21
|
+
sleep sleep_amount
|
22
|
+
retry
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
raise unless e.is_a?(Faraday::RetriableResponse)
|
27
|
+
|
28
|
+
e.response
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def retries_zero?(retries, env, exception)
|
34
|
+
retries.zero? && retry_request?(env, exception)
|
35
|
+
end
|
36
|
+
|
37
|
+
def exhausted_retries(options, env, exception)
|
38
|
+
options.exhausted_retries_block.call(
|
39
|
+
env: env,
|
40
|
+
exception: exception,
|
41
|
+
options: options
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday-retry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Giuffrida
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -151,17 +151,18 @@ files:
|
|
151
151
|
- lib/faraday/retriable_response.rb
|
152
152
|
- lib/faraday/retry.rb
|
153
153
|
- lib/faraday/retry/middleware.rb
|
154
|
+
- lib/faraday/retry/retryable.rb
|
154
155
|
- lib/faraday/retry/version.rb
|
155
156
|
homepage: https://github.com/lostisland/faraday-retry
|
156
157
|
licenses:
|
157
158
|
- MIT
|
158
159
|
metadata:
|
159
160
|
bug_tracker_uri: https://github.com/lostisland/faraday-retry/issues
|
160
|
-
changelog_uri: https://github.com/lostisland/faraday-retry/blob/v2.
|
161
|
-
documentation_uri: http://www.rubydoc.info/gems/faraday-retry/2.
|
161
|
+
changelog_uri: https://github.com/lostisland/faraday-retry/blob/v2.3.0/CHANGELOG.md
|
162
|
+
documentation_uri: http://www.rubydoc.info/gems/faraday-retry/2.3.0
|
162
163
|
homepage_uri: https://github.com/lostisland/faraday-retry
|
163
164
|
source_code_uri: https://github.com/lostisland/faraday-retry
|
164
|
-
post_install_message:
|
165
|
+
post_install_message:
|
165
166
|
rdoc_options: []
|
166
167
|
require_paths:
|
167
168
|
- lib
|
@@ -180,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
180
181
|
version: '0'
|
181
182
|
requirements: []
|
182
183
|
rubygems_version: 3.1.6
|
183
|
-
signing_key:
|
184
|
+
signing_key:
|
184
185
|
specification_version: 4
|
185
186
|
summary: Catches exceptions and retries each request a limited number of times
|
186
187
|
test_files: []
|