Class: Schwab::Middleware::RateLimit
- Inherits:
-
Faraday::Middleware
- Object
- Faraday::Middleware
- Schwab::Middleware::RateLimit
- Defined in:
- lib/schwab/middleware/rate_limit.rb
Overview
Faraday middleware for handling rate limits with exponential backoff
Constant Summary collapse
- DEFAULT_MAX_RETRIES =
Default maximum number of retries for rate-limited requests
3- DEFAULT_RETRY_DELAY =
Default initial retry delay in seconds
1- DEFAULT_BACKOFF_FACTOR =
Default exponential backoff factor for retries
2- RETRY_STATUSES =
Rate limited and Service Unavailable
[429, 503].freeze
Instance Method Summary collapse
-
#call(env) ⇒ Faraday::Response
Process the request with rate limit handling.
-
#initialize(app, options = {}) ⇒ RateLimit
constructor
A new instance of RateLimit.
Constructor Details
#initialize(app, options = {}) ⇒ RateLimit
Returns a new instance of RateLimit.
18 19 20 21 22 23 24 |
# File 'lib/schwab/middleware/rate_limit.rb', line 18 def initialize(app, = {}) super(app) @max_retries = [:max_retries] || DEFAULT_MAX_RETRIES @retry_delay = [:retry_delay] || DEFAULT_RETRY_DELAY @backoff_factor = [:backoff_factor] || DEFAULT_BACKOFF_FACTOR @logger = [:logger] end |
Instance Method Details
#call(env) ⇒ Faraday::Response
Process the request with rate limit handling
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/schwab/middleware/rate_limit.rb', line 29 def call(env) retries = 0 delay = @retry_delay begin response = @app.call(env) # Check if we should retry this response if should_retry?(response) && retries < @max_retries retries += 1 # Check for Retry-After header retry_after = response.headers["retry-after"] wait_time = retry_after ? parse_retry_after(retry_after) : delay log_retry(env, response, retries, wait_time) # Wait before retrying sleep(wait_time) # Exponential backoff for next retry delay *= @backoff_factor # Retry the request by raising a custom error raise Faraday::RetriableResponse.new(nil, response) end response rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e # Retry on network errors if retries < @max_retries retries += 1 log_retry_error(env, e, retries, delay) sleep(delay) delay *= @backoff_factor retry else raise e end rescue Faraday::RetriableResponse # This is our custom retry signal retry end end |