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) 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
- #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.
39 40 41 42 43 44 |
# File 'lib/labkit/rate_limit/result.rb', line 39 def initialize(error: false) @evaluations = [] @skip_rule = nil @error = error @most_constraining = nil end |
Instance Attribute Details
#evaluations ⇒ Object (readonly)
Returns the value of attribute evaluations.
33 34 35 |
# File 'lib/labkit/rate_limit/result.rb', line 33 def evaluations @evaluations end |
Class Method Details
.error ⇒ Object
35 36 37 |
# File 'lib/labkit/rate_limit/result.rb', line 35 def self.error new(error: true) end |
Instance Method Details
#action ⇒ Object
81 82 83 |
# File 'lib/labkit/rate_limit/result.rb', line 81 def action block? ? :block : :allow end |
#add_evaluation(evaluation) ⇒ Object
46 47 48 49 50 |
# File 'lib/labkit/rate_limit/result.rb', line 46 def add_evaluation(evaluation) @most_constraining = nil @evaluations << evaluation self end |
#block? ⇒ Boolean
67 68 69 |
# File 'lib/labkit/rate_limit/result.rb', line 67 def block? !skipped? && @evaluations.any?(&:block?) end |
#error? ⇒ Boolean
77 78 79 |
# File 'lib/labkit/rate_limit/result.rb', line 77 def error? @error end |
#exceeded? ⇒ Boolean
71 72 73 74 75 |
# File 'lib/labkit/rate_limit/result.rb', line 71 def exceeded? return false if skipped? !most_constraining.nil? && most_constraining.exceeded? end |
#info ⇒ Object
89 90 91 92 93 |
# File 'lib/labkit/rate_limit/result.rb', line 89 def info return nil if skipped? most_constraining&.info end |
#matched? ⇒ Boolean
59 60 61 |
# File 'lib/labkit/rate_limit/result.rb', line 59 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.
98 99 100 |
# File 'lib/labkit/rate_limit/result.rb', line 98 def most_constraining @most_constraining ||= @evaluations.min end |
#rule ⇒ Object
85 86 87 |
# File 'lib/labkit/rate_limit/result.rb', line 85 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.
54 55 56 57 |
# File 'lib/labkit/rate_limit/result.rb', line 54 def skip!(rule) @skip_rule = rule self end |
#skipped? ⇒ Boolean
63 64 65 |
# File 'lib/labkit/rate_limit/result.rb', line 63 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.
106 107 108 109 110 111 112 113 114 |
# File 'lib/labkit/rate_limit/result.rb', line 106 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 |