faraday-retry 1.0.3 → 2.0.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 +14 -0
- data/README.md +17 -9
- data/lib/faraday/retry/middleware.rb +41 -17
- data/lib/faraday/retry/version.rb +1 -1
- data/lib/faraday/retry.rb +1 -0
- metadata +132 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b07a16fd11fb4fcc1041260ad3e7341f40762eef86984f23ee5785c1c15b4334
|
4
|
+
data.tar.gz: 3551328efd8212c9f2079ce2e4b2b192271bfccc3c4df337f921f9403fefd742
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0a0b3718c1085d8c43f350ab4d82a21b508d215fc1caa59751d2552ee2598dc9281a5a21589d9cf08bad4a4b68925d6d6e27c592fe38fc3a40d6d2a606e0ce1
|
7
|
+
data.tar.gz: 891a2994edb8f81ea829710faa26b87056206be42d12092ce6c7250bb7cebaaaf1cd4363ce0f4d36307d12f1ecaa9a15385418bec80a2cab390b3f245f96ae54
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v2.0.0 (2022-06-08)
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
* `retry_block` now takes keyword arguments instead of positional (backwards incompatible)
|
8
|
+
* `retry_block`'s `retry_count` argument now counts up from 0, instead of old `retries_remaining`
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
* Support for the `RateLimit-Reset` header. [PR #9](https://github.com/lostisland/faraday-retry/pull/9). Thanks, [@maxprokopiev]!
|
13
|
+
* `retry_block` has additional `will_retry_in` argument with upcoming delay before retry in seconds.
|
14
|
+
|
3
15
|
## v1.0
|
4
16
|
|
5
17
|
Initial release.
|
@@ -8,3 +20,5 @@ This release consists of the same middleware that was previously bundled with Fa
|
|
8
20
|
### Fixed
|
9
21
|
|
10
22
|
* Retry middleware `retry_block` is not called if retry will not happen due to `max_interval`, https://github.com/lostisland/faraday/pull/1350
|
23
|
+
|
24
|
+
[@maxprokopiev]: https://github.com/maxprokopiev
|
data/README.md
CHANGED
@@ -96,11 +96,14 @@ retry_options = {
|
|
96
96
|
}
|
97
97
|
```
|
98
98
|
|
99
|
-
#### Automatically handle the `Retry-After`
|
99
|
+
#### Automatically handle the `Retry-After` and `RateLimit-Reset` headers
|
100
100
|
|
101
|
-
Some APIs, like the [Slack API](https://api.slack.com/docs/rate-limits), will inform you when you reach their API limits by replying with a response status code of `429`
|
101
|
+
Some APIs, like the [Slack API](https://api.slack.com/docs/rate-limits), will inform you when you reach their API limits by replying with a response status code of `429`
|
102
|
+
and a response header of `Retry-After` containing a time in seconds. You should then only retry querying after the amount of time provided by the `Retry-After` header,
|
103
|
+
otherwise you won't get a response. Other APIs communicate their rate limits via the [RateLimit-xxx](https://tools.ietf.org/id/draft-polli-ratelimit-headers-00.html#rfc.section.3.3) headers
|
104
|
+
where `RateLimit-Reset` behaves similarly to the `Retry-After`.
|
102
105
|
|
103
|
-
You can automatically handle
|
106
|
+
You can automatically handle both headers and have Faraday pause and retry for the right amount of time by including the `429` status code in the retry statuses list:
|
104
107
|
|
105
108
|
```ruby
|
106
109
|
retry_options = {
|
@@ -127,15 +130,19 @@ retry_options = {
|
|
127
130
|
|
128
131
|
### Call a block on every retry
|
129
132
|
|
130
|
-
You can specify a
|
131
|
-
There are many different applications for this feature, spacing from instrumentation to monitoring.
|
132
|
-
|
133
|
+
You can specify a proc object through the `retry_block` option that will be called before every
|
134
|
+
retry, before There are many different applications for this feature, spacing from instrumentation to monitoring.
|
135
|
+
|
136
|
+
|
137
|
+
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)
|
138
|
+
|
139
|
+
|
133
140
|
For example, you might want to keep track of the response statuses:
|
134
141
|
|
135
142
|
```ruby
|
136
143
|
response_statuses = []
|
137
144
|
retry_options = {
|
138
|
-
retry_block: -> (env
|
145
|
+
retry_block: -> (env:, options:, retries_remaining:, exception:, will_retry_in:) { response_statuses << env.status }
|
139
146
|
}
|
140
147
|
```
|
141
148
|
|
@@ -147,8 +154,9 @@ Then, run `bin/test` to run the tests.
|
|
147
154
|
|
148
155
|
To install this gem onto your local machine, run `rake build`.
|
149
156
|
|
150
|
-
|
151
|
-
|
157
|
+
### Releasing a new version
|
158
|
+
|
159
|
+
To release a new version, make a commit with a message such as "Bumped to 0.0.2", and change the _Unreleased_ heading in `CHANGELOG.md` to a heading like "0.0.2 (2022-01-01)", and then use GitHub Releases to author a release. A GitHub Actions workflow then publishes a new gem to [RubyGems.org](https://rubygems.org/gems/faraday-retry).
|
152
160
|
|
153
161
|
## Contributing
|
154
162
|
|
@@ -71,7 +71,7 @@ module Faraday
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def retry_block
|
74
|
-
self[:retry_block] ||= proc {}
|
74
|
+
self[:retry_block] ||= proc {}
|
75
75
|
end
|
76
76
|
|
77
77
|
def retry_statuses
|
@@ -105,8 +105,16 @@ module Faraday
|
|
105
105
|
# if the exception produced is non-recoverable or if the
|
106
106
|
# the HTTP method called is not idempotent.
|
107
107
|
# @option options [Block] :retry_block block that is executed before
|
108
|
-
# every retry.
|
109
|
-
#
|
108
|
+
# every retry. The block will be yielded keyword arguments:
|
109
|
+
# * env [Faraday::Env]: Request environment
|
110
|
+
# * options [Faraday::Options]: middleware options
|
111
|
+
# * retry_count [Integer]: how many retries have already occured (starts at 0)
|
112
|
+
# * exception [Exception]: exception that triggered the retry,
|
113
|
+
# will be the synthetic `Faraday::RetriableResponse` if the
|
114
|
+
# retry was triggered by something other than an exception.
|
115
|
+
# * will_retry_in [Float]: retry_block is called *before* the retry
|
116
|
+
# delay, actual retry will happen in will_retry_in number of
|
117
|
+
# seconds.
|
110
118
|
# @option options [Array] :retry_statuses Array of Integer HTTP status
|
111
119
|
# codes or a single Integer value that determines whether to raise
|
112
120
|
# a Faraday::RetriableResponse exception based on the HTTP status code
|
@@ -118,7 +126,7 @@ module Faraday
|
|
118
126
|
end
|
119
127
|
|
120
128
|
def calculate_sleep_amount(retries, env)
|
121
|
-
retry_after = calculate_retry_after(env)
|
129
|
+
retry_after = [calculate_retry_after(env), calculate_rate_limit_reset(env)].compact.max
|
122
130
|
retry_interval = calculate_retry_interval(retries)
|
123
131
|
|
124
132
|
return if retry_after && retry_after > @options.max_interval
|
@@ -145,7 +153,13 @@ module Faraday
|
|
145
153
|
retries -= 1
|
146
154
|
rewind_files(request_body)
|
147
155
|
if (sleep_amount = calculate_sleep_amount(retries + 1, env))
|
148
|
-
@options.retry_block.call(
|
156
|
+
@options.retry_block.call(
|
157
|
+
env: env,
|
158
|
+
options: @options,
|
159
|
+
retry_count: @options.max - (retries + 1),
|
160
|
+
exception: e,
|
161
|
+
will_retry_in: sleep_amount
|
162
|
+
)
|
149
163
|
sleep sleep_amount
|
150
164
|
retry
|
151
165
|
end
|
@@ -198,21 +212,16 @@ module Faraday
|
|
198
212
|
end
|
199
213
|
end
|
200
214
|
|
215
|
+
# RFC for RateLimit Header Fields for HTTP:
|
216
|
+
# https://tools.ietf.org/id/draft-polli-ratelimit-headers-00.html#rfc.section.3.3
|
217
|
+
def calculate_rate_limit_reset(env)
|
218
|
+
parse_retry_header(env, 'RateLimit-Reset')
|
219
|
+
end
|
220
|
+
|
201
221
|
# MDN spec for Retry-After header:
|
202
222
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
203
223
|
def calculate_retry_after(env)
|
204
|
-
|
205
|
-
return unless response_headers
|
206
|
-
|
207
|
-
retry_after_value = env[:response_headers]['Retry-After']
|
208
|
-
|
209
|
-
# Try to parse date from the header value
|
210
|
-
begin
|
211
|
-
datetime = DateTime.rfc2822(retry_after_value)
|
212
|
-
datetime.to_time - Time.now.utc
|
213
|
-
rescue ArgumentError
|
214
|
-
retry_after_value.to_f
|
215
|
-
end
|
224
|
+
parse_retry_header(env, 'Retry-After')
|
216
225
|
end
|
217
226
|
|
218
227
|
def calculate_retry_interval(retries)
|
@@ -225,6 +234,21 @@ module Faraday
|
|
225
234
|
|
226
235
|
current_interval + random_interval
|
227
236
|
end
|
237
|
+
|
238
|
+
def parse_retry_header(env, header)
|
239
|
+
response_headers = env[:response_headers]
|
240
|
+
return unless response_headers
|
241
|
+
|
242
|
+
retry_after_value = env[:response_headers][header]
|
243
|
+
|
244
|
+
# Try to parse date from the header value
|
245
|
+
begin
|
246
|
+
datetime = DateTime.rfc2822(retry_after_value)
|
247
|
+
datetime.to_time - Time.now.utc
|
248
|
+
rescue ArgumentError
|
249
|
+
retry_after_value.to_f
|
250
|
+
end
|
251
|
+
end
|
228
252
|
end
|
229
253
|
end
|
230
254
|
end
|
data/lib/faraday/retry.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,141 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday-retry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Giuffrida
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
12
|
-
dependencies:
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.21.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.21.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.21.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.21.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-packaging
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.5.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.5.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-performance
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.0'
|
13
139
|
description: 'Catches exceptions and retries each request a limited number of times.
|
14
140
|
|
15
141
|
'
|
@@ -31,11 +157,10 @@ licenses:
|
|
31
157
|
- MIT
|
32
158
|
metadata:
|
33
159
|
bug_tracker_uri: https://github.com/lostisland/faraday-retry/issues
|
34
|
-
changelog_uri: https://github.com/lostisland/faraday-retry/blob/
|
35
|
-
documentation_uri: http://www.rubydoc.info/gems/faraday-retry/
|
160
|
+
changelog_uri: https://github.com/lostisland/faraday-retry/blob/v2.0.0/CHANGELOG.md
|
161
|
+
documentation_uri: http://www.rubydoc.info/gems/faraday-retry/2.0.0
|
36
162
|
homepage_uri: https://github.com/lostisland/faraday-retry
|
37
163
|
source_code_uri: https://github.com/lostisland/faraday-retry
|
38
|
-
wiki_uri: https://github.com/lostisland/faraday-retry/wiki
|
39
164
|
post_install_message:
|
40
165
|
rdoc_options: []
|
41
166
|
require_paths:
|
@@ -44,7 +169,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
169
|
requirements:
|
45
170
|
- - ">="
|
46
171
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
172
|
+
version: '2.6'
|
48
173
|
- - "<"
|
49
174
|
- !ruby/object:Gem::Version
|
50
175
|
version: '4'
|