faraday-retry 1.0.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2693714c55f145be183aac73aced8352a5683031372eee3211298a207c591997
4
- data.tar.gz: a4f3b4c56224c2091bdbe5ff7b44f3f1c93438293bd9027c1441cf0287b42a01
3
+ metadata.gz: b07a16fd11fb4fcc1041260ad3e7341f40762eef86984f23ee5785c1c15b4334
4
+ data.tar.gz: 3551328efd8212c9f2079ce2e4b2b192271bfccc3c4df337f921f9403fefd742
5
5
  SHA512:
6
- metadata.gz: 86639f396dba9b1dd87a7879408e08f8fdc894a9949bfde95ca070190b7e195f0de07c31b96f8af18bfee03bd92be6744c90e63b1f4491c242f38f8bb1661fab
7
- data.tar.gz: aca22dc17015c52f898519b49428140ef5835627f85510e3bd23091e706a3405917a11829e652b0eaca33c73861342bb372e780f363dc867c9328c370776bcd1
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` header
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` 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, otherwise you won't get a response.
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 this and have Faraday pause and retry for the right amount of time by including the `429` status code in the retry statuses list:
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 block through the `retry_block` option that will be called before every retry.
131
- There are many different applications for this feature, spacing from instrumentation to monitoring.
132
- Request environment, middleware options, current number of retries and the exception is passed to the block as parameters.
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, options, retries, exc) { response_statuses << env.status }
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
- To release a new version, make a commit with a message such as "Bumped to 0.0.2" and then run `rake release`.
151
- See how it works [here](https://bundler.io/guides/creating_gem.html#releasing-the-gem).
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
 
@@ -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. Request environment, middleware options, current number
109
- # of retries and the exception is passed to the block as parameters.
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(env, @options, retries, e)
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
- response_headers = env[:response_headers]
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Faraday
4
4
  module Retry
5
- VERSION = '1.0.1'
5
+ VERSION = '2.0.0'
6
6
  end
7
7
  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: 1.0.1
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-01-04 00:00:00.000000000 Z
11
+ date: 2022-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -157,11 +157,10 @@ licenses:
157
157
  - MIT
158
158
  metadata:
159
159
  bug_tracker_uri: https://github.com/lostisland/faraday-retry/issues
160
- changelog_uri: https://github.com/lostisland/faraday-retry/blob/v1.0.1/CHANGELOG.md
161
- documentation_uri: http://www.rubydoc.info/gems/faraday-retry/1.0.1
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
162
162
  homepage_uri: https://github.com/lostisland/faraday-retry
163
163
  source_code_uri: https://github.com/lostisland/faraday-retry
164
- wiki_uri: https://github.com/lostisland/faraday-retry/wiki
165
164
  post_install_message:
166
165
  rdoc_options: []
167
166
  require_paths: