Class: Wurk::Limiter::Bucket
Overview
Cardinal-boundary counter. Reset at the top of the unit (00:00 of minute/hour/day). On exhaustion sleep until next boundary, retry, OverLimit if that exceeds wait_timeout.
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#initialize(name, **options) ⇒ Bucket
constructor
A new instance of Bucket.
- #size ⇒ Object
-
#status ⇒ Object
used = this period’s count; limit = count; reset_at = the next cardinal boundary, when the counter rolls back to zero (#16).
- #type ⇒ Object
- #within_limit(used: 1, &block) ⇒ Object
Methods inherited from Base
Constructor Details
#initialize(name, **options) ⇒ Bucket
Returns a new instance of Bucket.
13 14 15 16 17 18 |
# File 'lib/wurk/limiter/bucket.rb', line 13 def initialize(name, **) # Eager interval validation so a typo in `:fortnight` blows up at boot, # not at first call. Lazy validation defers failures to runtime. Limiter.interval_seconds([:interval], allow_integer: false) super end |
Instance Method Details
#size ⇒ Object
20 21 22 |
# File 'lib/wurk/limiter/bucket.rb', line 20 def size Wurk::Limiter.redis { |c| (c.call('GET', epoch_key) || '0').to_i } end |
#status ⇒ Object
used = this period’s count; limit = count; reset_at = the next cardinal boundary, when the counter rolls back to zero (#16).
26 27 28 |
# File 'lib/wurk/limiter/bucket.rb', line 26 def status build_status(used: size, limit: @options[:count], reset_at: next_boundary) end |
#type ⇒ Object
11 |
# File 'lib/wurk/limiter/bucket.rb', line 11 def type = :bucket |
#within_limit(used: 1, &block) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/wurk/limiter/bucket.rb', line 30 def within_limit(used: 1, &block) raise ArgumentError, 'block required' unless block deadline = ::Time.now.to_f + @options[:wait_timeout] loop do ok, _current, secs_to_next = acquire(used) return block.call if ok.to_i == 1 remaining = deadline - ::Time.now.to_f raise OverLimit, self if remaining <= 0 sleep [remaining, secs_to_next.to_f, 0.05].compact.min.clamp(0.0, remaining) end end |