Class: Labkit::RateLimit::Result
- Inherits:
-
Object
- Object
- Labkit::RateLimit::Result
- Defined in:
- lib/labkit/rate_limit/result.rb
Overview
Result is the return value of Limiter#check.
It accumulates one Result::Evaluation per matched-and-counted rule; the reader methods report the single most-constraining evaluation (see #most_constraining). A matched :skip rule or a fail-open error replaces the evaluations as the source of the reported outcome.
Result is a mutable accumulator, not a value object: two Results built from the same evaluations are not #==.
matched? - true if at least one rule's match conditions were satisfied exceeded? - true if the reported evaluation's counter exceeded its limit action - the outcome: what the caller should do :block = a :limit rule matched and is over its limit :allow = everything else, including an exceeded :log rule (visible via exceeded?), a matched :skip rule, no rule matched, and error (fail-open). The rule's configured action is available via rule.action. rule - the reported Rule: the :skip rule when one matched, otherwise the most-constraining evaluated Rule (nil when matched? is false). Other rules may also have matched and been counted; see #evaluations. error? - true if Redis was unavailable; result fails open (exceeded? is false) degraded? - true if a matched count_distinct rule was skipped by the missing-key fail-open path; the check still completed info - Result::Info with per-window counters for the reported rule; nil when matched? is false, error?, or the matched rule is :skip (no counter exists) evaluations - every counted evaluation, in rule declaration order
Defined Under Namespace
Classes: Evaluation, Info
Instance Attribute Summary collapse
-
#evaluations ⇒ Object
readonly
Returns the value of attribute evaluations.
Class Method Summary collapse
Instance Method Summary collapse
- #action ⇒ Object
- #add_evaluation(evaluation) ⇒ Object
- #block? ⇒ Boolean
-
#degraded! ⇒ Object
Unlike error?, the check keeps going: the flag marks the outcome as degraded without changing it.
- #degraded? ⇒ Boolean
- #error? ⇒ Boolean
- #exceeded? ⇒ Boolean
- #info ⇒ Object
-
#initialize(error: false) ⇒ Result
constructor
A new instance of Result.
- #matched? ⇒ Boolean
-
#most_constraining ⇒ Object
The evaluation with the strongest claim on the outcome; ties keep the earliest-declared rule (min returns the first of tied elements).
- #rule ⇒ Object
-
#skip!(rule) ⇒ Object
Records a matched :skip rule: the request is allowed and the skip rule is the one reported, regardless of any evaluations already collected.
- #skipped? ⇒ Boolean
-
#to_response_headers ⇒ Object
Returns RFC-compliant rate limit response headers, or {} when no rule matched or an error occurred.
Constructor Details
#initialize(error: false) ⇒ Result
Returns a new instance of Result.
41 42 43 44 45 46 47 |
# File 'lib/labkit/rate_limit/result.rb', line 41 def initialize(error: false) @evaluations = [] @skip_rule = nil @error = error @degraded = false @most_constraining = nil end |
Instance Attribute Details
#evaluations ⇒ Object (readonly)
Returns the value of attribute evaluations.
35 36 37 |
# File 'lib/labkit/rate_limit/result.rb', line 35 def evaluations @evaluations end |
Class Method Details
.error ⇒ Object
37 38 39 |
# File 'lib/labkit/rate_limit/result.rb', line 37 def self.error new(error: true) end |
Instance Method Details
#action ⇒ Object
95 96 97 |
# File 'lib/labkit/rate_limit/result.rb', line 95 def action block? ? :block : :allow end |
#add_evaluation(evaluation) ⇒ Object
49 50 51 52 53 |
# File 'lib/labkit/rate_limit/result.rb', line 49 def add_evaluation(evaluation) @most_constraining = nil @evaluations << evaluation self end |
#block? ⇒ Boolean
70 71 72 |
# File 'lib/labkit/rate_limit/result.rb', line 70 def block? !skipped? && @evaluations.any?(&:block?) end |
#degraded! ⇒ Object
Unlike error?, the check keeps going: the flag marks the outcome as degraded without changing it.
86 87 88 89 |
# File 'lib/labkit/rate_limit/result.rb', line 86 def degraded! @degraded = true self end |
#degraded? ⇒ Boolean
91 92 93 |
# File 'lib/labkit/rate_limit/result.rb', line 91 def degraded? @degraded end |
#error? ⇒ Boolean
80 81 82 |
# File 'lib/labkit/rate_limit/result.rb', line 80 def error? @error end |
#exceeded? ⇒ Boolean
74 75 76 77 78 |
# File 'lib/labkit/rate_limit/result.rb', line 74 def exceeded? return false if skipped? !most_constraining.nil? && most_constraining.exceeded? end |
#info ⇒ Object
103 104 105 106 107 |
# File 'lib/labkit/rate_limit/result.rb', line 103 def info return nil if skipped? most_constraining&.info end |
#matched? ⇒ Boolean
62 63 64 |
# File 'lib/labkit/rate_limit/result.rb', line 62 def matched? skipped? || @evaluations.any? end |
#most_constraining ⇒ Object
The evaluation with the strongest claim on the outcome; ties keep the earliest-declared rule (min returns the first of tied elements). Memoized; add_evaluation invalidates.
112 113 114 |
# File 'lib/labkit/rate_limit/result.rb', line 112 def most_constraining @most_constraining ||= @evaluations.min end |
#rule ⇒ Object
99 100 101 |
# File 'lib/labkit/rate_limit/result.rb', line 99 def rule @skip_rule || most_constraining&.rule end |
#skip!(rule) ⇒ Object
Records a matched :skip rule: the request is allowed and the skip rule is the one reported, regardless of any evaluations already collected.
57 58 59 60 |
# File 'lib/labkit/rate_limit/result.rb', line 57 def skip!(rule) @skip_rule = rule self end |
#skipped? ⇒ Boolean
66 67 68 |
# File 'lib/labkit/rate_limit/result.rb', line 66 def skipped? !!@skip_rule end |
#to_response_headers ⇒ Object
Returns RFC-compliant rate limit response headers, or {} when no rule matched or an error occurred. Keys: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset (Unix timestamp). remaining is coerced to Integer for header output even when info.remaining is fractional; the RateLimit header spec requires integer values.
120 121 122 123 124 125 126 127 128 |
# File 'lib/labkit/rate_limit/result.rb', line 120 def to_response_headers return {} unless matched? && !error? && info { "RateLimit-Limit" => info.resolved_limit.to_i.to_s, "RateLimit-Remaining" => info.remaining.to_i.to_s, "RateLimit-Reset" => info.reset_at.to_i.to_s } end |