faraday-retry 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +6 -0
- data/LICENSE.md +21 -0
- data/README.md +161 -0
- data/lib/faraday/retriable_response.rb +8 -0
- data/lib/faraday/retry/middleware.rb +229 -0
- data/lib/faraday/retry/version.rb +7 -0
- data/lib/faraday/retry.rb +13 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a1e1671b917edb92ca89a4cebdd676bc6dfbc63956ef5d17a79bb467dd8134b9
|
4
|
+
data.tar.gz: b29b41e84db3b281a91fbef905925579d3d9ab003dba97e66c2dc906d1ed0d60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 56bc36544781fe865ba266157f5f07365e69e2efb4aa51fce0e638dec8b19a14e9b1be68f3401e43db7bc76daaf278edcd457fb693f6b314f901c270eb78f3bd
|
7
|
+
data.tar.gz: 363570c19fb872444515db4caa4fda1ba3f135510ce0e6d67d32ab8005d73b06270a48ea41b03ac7b707ae63f97f47b92145dbfeb25e28a546691b147328a3ed
|
data/CHANGELOG.md
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Mattia Giuffrida
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# Faraday Retry
|
2
|
+
|
3
|
+
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/lostisland/faraday-retry/CI)](https://github.com/lostisland/faraday-retry/actions?query=branch%3Amain)
|
4
|
+
[![Gem](https://img.shields.io/gem/v/faraday-retry.svg?style=flat-square)](https://rubygems.org/gems/faraday-retry)
|
5
|
+
[![License](https://img.shields.io/github/license/lostisland/faraday-retry.svg?style=flat-square)](LICENSE.md)
|
6
|
+
|
7
|
+
The `Retry` middleware automatically retries requests that fail due to intermittent client
|
8
|
+
or server errors (such as network hiccups).
|
9
|
+
By default, it retries 2 times and handles only timeout exceptions.
|
10
|
+
It can be configured with an arbitrary number of retries, a list of exceptions to handle,
|
11
|
+
a retry interval, a percentage of randomness to add to the retry interval, and a backoff factor.
|
12
|
+
The middleware can also handle the [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After)
|
13
|
+
header automatically when configured with the right status codes (see below for an example).
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'faraday-retry'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
```shell
|
26
|
+
bundle install
|
27
|
+
```
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
```shell
|
32
|
+
gem install faraday-retry
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
This example will result in a first interval that is random between 0.05 and 0.075
|
38
|
+
and a second interval that is random between 0.1 and 0.125.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require 'faraday'
|
42
|
+
require 'faraday/retry'
|
43
|
+
|
44
|
+
retry_options = {
|
45
|
+
max: 2,
|
46
|
+
interval: 0.05,
|
47
|
+
interval_randomness: 0.5,
|
48
|
+
backoff_factor: 2
|
49
|
+
}
|
50
|
+
|
51
|
+
conn = Faraday.new(...) do |f|
|
52
|
+
f.request :retry, retry_options
|
53
|
+
#...
|
54
|
+
end
|
55
|
+
|
56
|
+
conn.get('/')
|
57
|
+
```
|
58
|
+
|
59
|
+
### Control when the middleware will retry requests
|
60
|
+
|
61
|
+
By default, the `Retry` middleware will only retry idempotent methods and the most common network-related exceptions.
|
62
|
+
You can change this behaviour by providing the right option when adding the middleware to your connection.
|
63
|
+
|
64
|
+
#### Specify which methods will be retried
|
65
|
+
|
66
|
+
You can provide a `methods` option with a list of HTTP methods.
|
67
|
+
This will replace the default list of HTTP methods: `delete`, `get`, `head`, `options`, `put`.
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
retry_options = {
|
71
|
+
methods: %i[get post]
|
72
|
+
}
|
73
|
+
```
|
74
|
+
|
75
|
+
#### Specify which exceptions should trigger a retry
|
76
|
+
|
77
|
+
You can provide an `exceptions` option with a list of exceptions that will replace
|
78
|
+
the default list of network-related exceptions: `Errno::ETIMEDOUT`, `Timeout::Error`, `Faraday::TimeoutError`.
|
79
|
+
This can be particularly useful when combined with the [RaiseError][raise_error] middleware.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
retry_options = {
|
83
|
+
exceptions: [Faraday::ResourceNotFound, Faraday::UnauthorizedError]
|
84
|
+
}
|
85
|
+
```
|
86
|
+
|
87
|
+
#### Specify on which response statuses to retry
|
88
|
+
|
89
|
+
By default the `Retry` middleware will only retry the request if one of the expected exceptions arise.
|
90
|
+
However, you can specify a list of HTTP statuses you'd like to be retried. When you do so, the middleware will
|
91
|
+
check the response `status` code and will retry the request if included in the list.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
retry_options = {
|
95
|
+
retry_statuses: [401, 409]
|
96
|
+
}
|
97
|
+
```
|
98
|
+
|
99
|
+
#### Automatically handle the `Retry-After` header
|
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.
|
102
|
+
|
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:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
retry_options = {
|
107
|
+
retry_statuses: [429]
|
108
|
+
}
|
109
|
+
```
|
110
|
+
|
111
|
+
#### Specify a custom retry logic
|
112
|
+
|
113
|
+
You can also specify a custom retry logic with the `retry_if` option.
|
114
|
+
This option accepts a block that will receive the `env` object and the exception raised
|
115
|
+
and should decide if the code should retry still the action or not independent of the retry count.
|
116
|
+
This would be useful if the exception produced is non-recoverable or if the the HTTP method called is not idempotent.
|
117
|
+
|
118
|
+
**NOTE:** this option will only be used for methods that are not included in the `methods` option.
|
119
|
+
If you want this to apply to all HTTP methods, pass `methods: []` as an additional option.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# Retries the request if response contains { success: false }
|
123
|
+
retry_options = {
|
124
|
+
retry_if: -> (env, _exc) { env.body[:success] == 'false' }
|
125
|
+
}
|
126
|
+
```
|
127
|
+
|
128
|
+
### Call a block on every retry
|
129
|
+
|
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
|
+
For example, you might want to keep track of the response statuses:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
response_statuses = []
|
137
|
+
retry_options = {
|
138
|
+
retry_block: -> (env, options, retries, exc) { response_statuses << env.status }
|
139
|
+
}
|
140
|
+
```
|
141
|
+
|
142
|
+
## Development
|
143
|
+
|
144
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
145
|
+
|
146
|
+
Then, run `bin/test` to run the tests.
|
147
|
+
|
148
|
+
To install this gem onto your local machine, run `rake build`.
|
149
|
+
|
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).
|
152
|
+
|
153
|
+
## Contributing
|
154
|
+
|
155
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/lostisland/faraday-retry).
|
156
|
+
|
157
|
+
## License
|
158
|
+
|
159
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
160
|
+
|
161
|
+
[raise_error]: https://lostisland.github.io/faraday/middleware/raise-error
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
module Retry
|
5
|
+
# This class provides the main implementation for your middleware.
|
6
|
+
# Your middleware can implement any of the following methods:
|
7
|
+
# * on_request - called when the request is being prepared
|
8
|
+
# * on_complete - called when the response is being processed
|
9
|
+
#
|
10
|
+
# Optionally, you can also override the following methods from Faraday::Middleware
|
11
|
+
# * initialize(app, options = {}) - the initializer method
|
12
|
+
# * call(env) - the main middleware invocation method.
|
13
|
+
# This already calls on_request and on_complete, so you normally don't need to override it.
|
14
|
+
# You may need to in case you need to "wrap" the request or need more control
|
15
|
+
# (see "retry" middleware: https://github.com/lostisland/faraday/blob/main/lib/faraday/request/retry.rb#L142).
|
16
|
+
# IMPORTANT: Remember to call `@app.call(env)` or `super` to not interrupt the middleware chain!
|
17
|
+
class Middleware < Faraday::Middleware
|
18
|
+
DEFAULT_EXCEPTIONS = [
|
19
|
+
Errno::ETIMEDOUT, 'Timeout::Error',
|
20
|
+
Faraday::TimeoutError, Faraday::RetriableResponse
|
21
|
+
].freeze
|
22
|
+
IDEMPOTENT_METHODS = %i[delete get head options put].freeze
|
23
|
+
|
24
|
+
# Options contains the configurable parameters for the Retry middleware.
|
25
|
+
class Options < Faraday::Options.new(:max, :interval, :max_interval,
|
26
|
+
:interval_randomness,
|
27
|
+
:backoff_factor, :exceptions,
|
28
|
+
:methods, :retry_if, :retry_block,
|
29
|
+
:retry_statuses)
|
30
|
+
|
31
|
+
DEFAULT_CHECK = ->(_env, _exception) { false }
|
32
|
+
|
33
|
+
def self.from(value)
|
34
|
+
if value.is_a?(Integer)
|
35
|
+
new(value)
|
36
|
+
else
|
37
|
+
super(value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def max
|
42
|
+
(self[:max] ||= 2).to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
def interval
|
46
|
+
(self[:interval] ||= 0).to_f
|
47
|
+
end
|
48
|
+
|
49
|
+
def max_interval
|
50
|
+
(self[:max_interval] ||= Float::MAX).to_f
|
51
|
+
end
|
52
|
+
|
53
|
+
def interval_randomness
|
54
|
+
(self[:interval_randomness] ||= 0).to_f
|
55
|
+
end
|
56
|
+
|
57
|
+
def backoff_factor
|
58
|
+
(self[:backoff_factor] ||= 1).to_f
|
59
|
+
end
|
60
|
+
|
61
|
+
def exceptions
|
62
|
+
Array(self[:exceptions] ||= DEFAULT_EXCEPTIONS)
|
63
|
+
end
|
64
|
+
|
65
|
+
def methods
|
66
|
+
Array(self[:methods] ||= IDEMPOTENT_METHODS)
|
67
|
+
end
|
68
|
+
|
69
|
+
def retry_if
|
70
|
+
self[:retry_if] ||= DEFAULT_CHECK
|
71
|
+
end
|
72
|
+
|
73
|
+
def retry_block
|
74
|
+
self[:retry_block] ||= proc {}
|
75
|
+
end
|
76
|
+
|
77
|
+
def retry_statuses
|
78
|
+
Array(self[:retry_statuses] ||= [])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param app [#call]
|
83
|
+
# @param options [Hash]
|
84
|
+
# @option options [Integer] :max (2) Maximum number of retries
|
85
|
+
# @option options [Integer] :interval (0) Pause in seconds between retries
|
86
|
+
# @option options [Integer] :interval_randomness (0) The maximum random
|
87
|
+
# interval amount expressed as a float between
|
88
|
+
# 0 and 1 to use in addition to the interval.
|
89
|
+
# @option options [Integer] :max_interval (Float::MAX) An upper limit
|
90
|
+
# for the interval
|
91
|
+
# @option options [Integer] :backoff_factor (1) The amount to multiply
|
92
|
+
# each successive retry's interval amount by in order to provide backoff
|
93
|
+
# @option options [Array] :exceptions ([ Errno::ETIMEDOUT,
|
94
|
+
# 'Timeout::Error', Faraday::TimeoutError, Faraday::RetriableResponse])
|
95
|
+
# The list of exceptions to handle. Exceptions can be given as
|
96
|
+
# Class, Module, or String.
|
97
|
+
# @option options [Array] :methods (the idempotent HTTP methods
|
98
|
+
# in IDEMPOTENT_METHODS) A list of HTTP methods to retry without
|
99
|
+
# calling retry_if. Pass an empty Array to call retry_if
|
100
|
+
# for all exceptions.
|
101
|
+
# @option options [Block] :retry_if (false) block that will receive
|
102
|
+
# the env object and the exception raised
|
103
|
+
# and should decide if the code should retry still the action or
|
104
|
+
# not independent of the retry count. This would be useful
|
105
|
+
# if the exception produced is non-recoverable or if the
|
106
|
+
# the HTTP method called is not idempotent.
|
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.
|
110
|
+
# @option options [Array] :retry_statuses Array of Integer HTTP status
|
111
|
+
# codes or a single Integer value that determines whether to raise
|
112
|
+
# a Faraday::RetriableResponse exception based on the HTTP status code
|
113
|
+
# of an HTTP response.
|
114
|
+
def initialize(app, options = nil)
|
115
|
+
super(app)
|
116
|
+
@options = Options.from(options)
|
117
|
+
@errmatch = build_exception_matcher(@options.exceptions)
|
118
|
+
end
|
119
|
+
|
120
|
+
def calculate_sleep_amount(retries, env)
|
121
|
+
retry_after = calculate_retry_after(env)
|
122
|
+
retry_interval = calculate_retry_interval(retries)
|
123
|
+
|
124
|
+
return if retry_after && retry_after > @options.max_interval
|
125
|
+
|
126
|
+
if retry_after && retry_after >= retry_interval
|
127
|
+
retry_after
|
128
|
+
else
|
129
|
+
retry_interval
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# @param env [Faraday::Env]
|
134
|
+
def call(env)
|
135
|
+
retries = @options.max
|
136
|
+
request_body = env[:body]
|
137
|
+
begin
|
138
|
+
# after failure env[:body] is set to the response body
|
139
|
+
env[:body] = request_body
|
140
|
+
@app.call(env).tap do |resp|
|
141
|
+
raise Faraday::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
|
142
|
+
end
|
143
|
+
rescue @errmatch => e
|
144
|
+
if retries.positive? && retry_request?(env, e)
|
145
|
+
retries -= 1
|
146
|
+
rewind_files(request_body)
|
147
|
+
if (sleep_amount = calculate_sleep_amount(retries + 1, env))
|
148
|
+
@options.retry_block.call(env, @options, retries, e)
|
149
|
+
sleep sleep_amount
|
150
|
+
retry
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
raise unless e.is_a?(Faraday::RetriableResponse)
|
155
|
+
|
156
|
+
e.response
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# An exception matcher for the rescue clause can usually be any object
|
161
|
+
# that responds to `===`, but for Ruby 1.8 it has to be a Class or Module.
|
162
|
+
#
|
163
|
+
# @param exceptions [Array]
|
164
|
+
# @api private
|
165
|
+
# @return [Module] an exception matcher
|
166
|
+
def build_exception_matcher(exceptions)
|
167
|
+
matcher = Module.new
|
168
|
+
(
|
169
|
+
class << matcher
|
170
|
+
self
|
171
|
+
end).class_eval do
|
172
|
+
define_method(:===) do |error|
|
173
|
+
exceptions.any? do |ex|
|
174
|
+
if ex.is_a? Module
|
175
|
+
error.is_a? ex
|
176
|
+
else
|
177
|
+
Object.const_defined?(ex.to_s) && error.is_a?(Object.const_get(ex.to_s))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
matcher
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def retry_request?(env, exception)
|
188
|
+
@options.methods.include?(env[:method]) ||
|
189
|
+
@options.retry_if.call(env, exception)
|
190
|
+
end
|
191
|
+
|
192
|
+
def rewind_files(body)
|
193
|
+
return unless body.is_a?(Hash)
|
194
|
+
|
195
|
+
body.each do |_, value|
|
196
|
+
value.rewind if value.is_a?(UploadIO)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# MDN spec for Retry-After header:
|
201
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
202
|
+
def calculate_retry_after(env)
|
203
|
+
response_headers = env[:response_headers]
|
204
|
+
return unless response_headers
|
205
|
+
|
206
|
+
retry_after_value = env[:response_headers]['Retry-After']
|
207
|
+
|
208
|
+
# Try to parse date from the header value
|
209
|
+
begin
|
210
|
+
datetime = DateTime.rfc2822(retry_after_value)
|
211
|
+
datetime.to_time - Time.now.utc
|
212
|
+
rescue ArgumentError
|
213
|
+
retry_after_value.to_f
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def calculate_retry_interval(retries)
|
218
|
+
retry_index = @options.max - retries
|
219
|
+
current_interval = @options.interval *
|
220
|
+
(@options.backoff_factor**retry_index)
|
221
|
+
current_interval = [current_interval, @options.max_interval].min
|
222
|
+
random_interval = rand * @options.interval_randomness.to_f *
|
223
|
+
@options.interval
|
224
|
+
|
225
|
+
current_interval + random_interval
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require_relative 'retriable_response'
|
5
|
+
require_relative 'retry/middleware'
|
6
|
+
require_relative 'retry/version'
|
7
|
+
|
8
|
+
module Faraday
|
9
|
+
# Middleware main module.
|
10
|
+
module Retry
|
11
|
+
Faraday::Request.register_middleware(retry: Faraday::Retry::Middleware)
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: faraday-retry
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mattia Giuffrida
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-01-02 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.0.alpha.pre.4
|
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.0.alpha.pre.4
|
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'
|
139
|
+
description: 'Catches exceptions and retries each request a limited number of times.
|
140
|
+
|
141
|
+
'
|
142
|
+
email:
|
143
|
+
- giuffrida.mattia@gmail.com
|
144
|
+
executables: []
|
145
|
+
extensions: []
|
146
|
+
extra_rdoc_files: []
|
147
|
+
files:
|
148
|
+
- CHANGELOG.md
|
149
|
+
- LICENSE.md
|
150
|
+
- README.md
|
151
|
+
- lib/faraday/retriable_response.rb
|
152
|
+
- lib/faraday/retry.rb
|
153
|
+
- lib/faraday/retry/middleware.rb
|
154
|
+
- lib/faraday/retry/version.rb
|
155
|
+
homepage: https://github.com/lostisland/faraday-retry
|
156
|
+
licenses:
|
157
|
+
- MIT
|
158
|
+
metadata:
|
159
|
+
bug_tracker_uri: https://github.com/lostisland/faraday-retry/issues
|
160
|
+
changelog_uri: https://github.com/lostisland/faraday-retry/blob/v1.0.0/CHANGELOG.md
|
161
|
+
documentation_uri: http://www.rubydoc.info/gems/faraday-retry/1.0.0
|
162
|
+
homepage_uri: https://github.com/lostisland/faraday-retry
|
163
|
+
source_code_uri: https://github.com/lostisland/faraday-retry
|
164
|
+
wiki_uri: https://github.com/lostisland/faraday-retry/wiki
|
165
|
+
post_install_message:
|
166
|
+
rdoc_options: []
|
167
|
+
require_paths:
|
168
|
+
- lib
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '2.6'
|
174
|
+
- - "<"
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '4'
|
177
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
requirements: []
|
183
|
+
rubygems_version: 3.1.6
|
184
|
+
signing_key:
|
185
|
+
specification_version: 4
|
186
|
+
summary: Catches exceptions and retries each request a limited number of times
|
187
|
+
test_files: []
|