Class: Twitch::RateLimiter
- Inherits:
-
Object
- Object
- Twitch::RateLimiter
- Defined in:
- lib/twitch/rate_limiter.rb
Constant Summary collapse
- LIMIT_HEADER =
Twitch API rate limit header names
"ratelimit-limit".freeze
- REMAINING_HEADER =
"ratelimit-remaining".freeze
- RESET_HEADER =
"ratelimit-reset".freeze
Instance Attribute Summary collapse
-
#limit ⇒ Object
readonly
Returns the value of attribute limit.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#remaining ⇒ Object
readonly
Returns the value of attribute remaining.
-
#reset_at ⇒ Object
readonly
Returns the value of attribute reset_at.
Instance Method Summary collapse
-
#approaching_limit?(threshold: 10) ⇒ Boolean
Check if we’re approaching the rate limit.
-
#initialize(logger: nil) ⇒ RateLimiter
constructor
A new instance of RateLimiter.
-
#rate_limited? ⇒ Boolean
Check if rate limited (no remaining requests).
-
#reset ⇒ Object
Reset rate limit tracking.
-
#reset_in ⇒ Object
Get seconds until rate limit resets.
-
#status ⇒ Object
Get formatted status string.
-
#update(response_headers) ⇒ Object
Update rate limit info from response headers.
-
#wait_if_rate_limited(base_wait: 1.0, max_wait: 60.0) ⇒ Object
Wait if rate limited, with exponential backoff.
-
#warn_if_approaching(threshold: 10) ⇒ Object
Log rate limit warning if approaching threshold.
Constructor Details
#initialize(logger: nil) ⇒ RateLimiter
Returns a new instance of RateLimiter.
10 11 12 13 14 15 16 |
# File 'lib/twitch/rate_limiter.rb', line 10 def initialize(logger: nil) @limit = nil @remaining = nil @reset_at = nil @logger = logger @last_warn_at = nil end |
Instance Attribute Details
#limit ⇒ Object (readonly)
Returns the value of attribute limit.
8 9 10 |
# File 'lib/twitch/rate_limiter.rb', line 8 def limit @limit end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
8 9 10 |
# File 'lib/twitch/rate_limiter.rb', line 8 def logger @logger end |
#remaining ⇒ Object (readonly)
Returns the value of attribute remaining.
8 9 10 |
# File 'lib/twitch/rate_limiter.rb', line 8 def remaining @remaining end |
#reset_at ⇒ Object (readonly)
Returns the value of attribute reset_at.
8 9 10 |
# File 'lib/twitch/rate_limiter.rb', line 8 def reset_at @reset_at end |
Instance Method Details
#approaching_limit?(threshold: 10) ⇒ Boolean
Check if we’re approaching the rate limit
28 29 30 31 32 |
# File 'lib/twitch/rate_limiter.rb', line 28 def approaching_limit?(threshold: 10) return false if remaining.nil? || limit.nil? remaining <= threshold end |
#rate_limited? ⇒ Boolean
Check if rate limited (no remaining requests)
43 44 45 |
# File 'lib/twitch/rate_limiter.rb', line 43 def rate_limited? remaining == 0 end |
#reset ⇒ Object
Reset rate limit tracking
74 75 76 77 78 79 |
# File 'lib/twitch/rate_limiter.rb', line 74 def reset @limit = nil @remaining = nil @reset_at = nil @last_warn_at = nil end |
#reset_in ⇒ Object
Get seconds until rate limit resets
35 36 37 38 39 40 |
# File 'lib/twitch/rate_limiter.rb', line 35 def reset_in return nil if reset_at.nil? seconds = reset_at - Time.now.to_i [ seconds, 0 ].max # Ensure non-negative end |
#status ⇒ Object
Get formatted status string
82 83 84 85 86 87 88 |
# File 'lib/twitch/rate_limiter.rb', line 82 def status if limit.nil? || remaining.nil? "Rate limit info not available" else "#{remaining}/#{limit} requests remaining" end end |
#update(response_headers) ⇒ Object
Update rate limit info from response headers
19 20 21 22 23 24 25 |
# File 'lib/twitch/rate_limiter.rb', line 19 def update(response_headers) return unless response_headers @limit = response_headers[LIMIT_HEADER]&.to_i @remaining = response_headers[REMAINING_HEADER]&.to_i @reset_at = response_headers[RESET_HEADER]&.to_i end |
#wait_if_rate_limited(base_wait: 1.0, max_wait: 60.0) ⇒ Object
Wait if rate limited, with exponential backoff
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/twitch/rate_limiter.rb', line 61 def wait_if_rate_limited(base_wait: 1.0, max_wait: 60.0) return if !rate_limited? || reset_in.nil? wait_seconds = [ reset_in + 1, max_wait ].min # Add 1 second buffer if logger logger.warn("Rate limited. Waiting #{wait_seconds} seconds until reset at #{Time.at(reset_at)}") end sleep(wait_seconds) end |
#warn_if_approaching(threshold: 10) ⇒ Object
Log rate limit warning if approaching threshold
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/twitch/rate_limiter.rb', line 48 def warn_if_approaching(threshold: 10) return unless approaching_limit?(threshold: threshold) return unless logger return if recently_warned? @last_warn_at = Time.now logger.warn( "Twitch API rate limit approaching: #{remaining}/#{limit} requests remaining. " \ "Resets in #{reset_in} seconds." ) end |