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 {level, last} — Lua compares level vs bucket_size after leaking elapsed * drain_per_sec.

Constant Summary collapse

WAIT_SLEEP =
0.05

Instance Method Summary collapse

Constructor Details

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

Instance Method Details

#size ⇒ Object



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

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

#state_keys ⇒ Object (protected)



44
45
46
# File 'lib/wurk/limiter/leaky.rb', line 44

def state_keys
  [state_key]
end

#status ⇒ Object

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



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

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

#type ⇒ Object



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

def type = :leaky

#within_limit(&block) ⇒ Object

Raises:

  • (ArgumentError)


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

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