Class: Wurk::Limiter::Window

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

Overview

Sliding window via ZSET of timestamps. Accepts symbolic units or a raw Integer (in seconds). Used-units expand to N ZADDs in the Lua script so multi-charge calls remain atomic.

Constant Summary collapse

WAIT_SLEEP =
0.5

Instance Attribute Summary

Attributes inherited from Base

#name, #options

Instance Method Summary collapse

Methods inherited from Base

#delete, #fingerprint, #reset

Constructor Details

#initialize(name, **options) ⇒ Window

Returns a new instance of Window.



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

def initialize(name, **options)
  # Symbol or raw Integer (spec ยง1.2: window accepts both).
  Limiter.interval_seconds(options[:interval], allow_integer: true)
  super
end

Instance Method Details

#sizeObject



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

def size
  cutoff = ::Time.now.to_f - interval_seconds
  Wurk::Limiter.redis do |c|
    c.call('ZREMRANGEBYSCORE', state_key, '-inf', "(#{cutoff}")
    c.call('ZCARD', state_key).to_i
  end
end

#statusObject

used = entries still inside the window; limit = count; reset_at = when the oldest entry slides out (freeing a slot), or nil when idle (#16).



32
33
34
# File 'lib/wurk/limiter/window.rb', line 32

def status
  build_status(used: size, limit: @options[:count], reset_at: oldest_expiry)
end

#typeObject



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

def type = :window

#within_limit(used: 1, &block) ⇒ Object

Raises:

  • (ArgumentError)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/wurk/limiter/window.rb', line 36

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

  deadline = ::Time.now.to_f + @options[:wait_timeout]
  loop do
    ok, _current, _oldest = acquire(used)
    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