Class: Wurk::Limiter::Leaky

Inherits:
Base
  • Object
show all
Defined in:
lib/wurk/limiter/leaky.rb

Overview

Leaky bucket: drain rate = bucket_size / drain ops/sec. Stored as a HASH of last — Lua compares level vs bucket_size after leaking elapsed * drain_per_sec.

Constant Summary collapse

WAIT_SLEEP =
0.05

Instance Attribute Summary

Attributes inherited from Base

#name, #options

Instance Method Summary collapse

Methods inherited from Base

#delete, #fingerprint, #initialize, #reset

Constructor Details

This class inherits a constructor from Wurk::Limiter::Base

Instance Method Details

#sizeObject



15
16
17
18
# File 'lib/wurk/limiter/leaky.rb', line 15

def size
  h = Wurk::Limiter.redis { |c| c.call('HGET', state_key, 'level') }
  h.to_f
end

#statusObject

used = current fill level; limit = bucket_size; reset_at = when the steady drip frees a slot (only meaningful while full), else nil (#16).



22
23
24
25
26
27
# File 'lib/wurk/limiter/leaky.rb', line 22

def status
  level = size
  cap = @options[:bucket_size]
  reset_at = level >= cap ? ::Time.now.to_f + ((level - cap + 1) / drain_per_sec) : nil
  build_status(used: level, limit: cap, reset_at: reset_at)
end

#typeObject



13
# File 'lib/wurk/limiter/leaky.rb', line 13

def type = :leaky

#within_limit(&block) ⇒ Object

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/wurk/limiter/leaky.rb', line 29

def within_limit(&block)
  raise ArgumentError, 'block required' unless block

  deadline = ::Time.now.to_f + @options[:wait_timeout]
  loop do
    ok, _level = acquire
    return block.call if ok.to_i == 1

    remaining = deadline - ::Time.now.to_f
    raise OverLimit, self if remaining <= 0

    sleep [remaining, WAIT_SLEEP].min
  end
end