Module: Ihasa::Lua

Defined in:
lib/ihasa/lua.rb

Overview

Contains lua related logic

Constant Summary collapse

NOW_DECLARATION =
"  redis.replicate_commands()\n  local now = redis.call('TIME')\n  now = now[1] + now[2] * 10 ^ -6\n".freeze
ALLOWANCE_UPDATE_STATEMENT =
"  allowance = allowance + (elapsed * rate)\n  if allowance > burst then\n    allowance = burst\n  end\n".freeze
ELAPSED_STATEMENT =
'local elapsed = now - last'.freeze
SEP =
"\n".freeze
LOCAL_VARIABLES =
Ihasa::OPTIONS
.map { |key| to_local(key) }
.tap { |vars| vars << ELAPSED_STATEMENT }.join(SEP).freeze
TOKEN_BUCKET_ALGORITHM_BODY =
"  \#{LOCAL_VARIABLES}\n  \#{ALLOWANCE_UPDATE_STATEMENT}\n  local result = \#{Ihasa::NOK}\n  if allowance >= 1.0 then\n    allowance = allowance - 1.0\n    result = \#{Ihasa::OK}\n  end\n  \#{set(last, 'now')}\n  \#{set(allowance, 'allowance')}\n  return result\n".freeze
TOKEN_BUCKET_ALGORITHM =
"  \#{NOW_DECLARATION}\n  \#{TOKEN_BUCKET_ALGORITHM_BODY}\n".freeze
TOKEN_BUCKET_HASH =
Digest::SHA1.hexdigest(
  Lua::TOKEN_BUCKET_ALGORITHM
).freeze

Class Method Summary collapse

Class Method Details

.configuration(rate_value, burst_value, now_declaration = NOW_DECLARATION) ⇒ Object

Please note that the replicate_commands is mandatory when using a non deterministic command before writing shit to the redis instance for versions >= 3.2



26
27
28
29
30
31
32
33
34
# File 'lib/ihasa/lua.rb', line 26

def configuration(rate_value, burst_value, now_declaration = NOW_DECLARATION)
  "    \#{now_declaration}\n    \#{set rate, rate_value}\n    \#{set burst, burst_value}\n    \#{set allowance, burst_value}\n    \#{set last, 'now'}\n  LUA\nend\n"

.exists?(key) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/ihasa/lua.rb', line 52

def exists?(key)
  "redis.call('EXISTS', #{key})"
end

.fetch(key) ⇒ Object



40
41
42
# File 'lib/ihasa/lua.rb', line 40

def fetch(key)
  "KEYS[#{index key}]"
end

.get(key) ⇒ Object



44
45
46
# File 'lib/ihasa/lua.rb', line 44

def get(key)
  "tonumber(redis.call('GET', #{key}))"
end

.index(key) ⇒ Object



36
37
38
# File 'lib/ihasa/lua.rb', line 36

def index(key)
  Integer(Ihasa::OPTIONS.index(key)) + 1
end

.method_missing(sym, *args, &block) ⇒ Object



56
57
58
59
# File 'lib/ihasa/lua.rb', line 56

def method_missing(sym, *args, &block)
  super unless Ihasa::OPTIONS.include? sym
  fetch sym
end

.now_declaration(value) ⇒ Object



19
20
21
# File 'lib/ihasa/lua.rb', line 19

def now_declaration(value)
  "local now = #{value}"
end

.set(key, value) ⇒ Object



48
49
50
# File 'lib/ihasa/lua.rb', line 48

def set(key, value)
  "redis.call('SET', #{key}, tostring(#{value}))"
end

.to_local(key) ⇒ Object



61
62
63
# File 'lib/ihasa/lua.rb', line 61

def to_local(key)
  "local #{key} = tonumber(#{get(fetch(key))})"
end

.token_bucket_algorithm_legacy(now_value) ⇒ Object



65
66
67
68
69
70
# File 'lib/ihasa/lua.rb', line 65

def token_bucket_algorithm_legacy(now_value)
  "    \#{now_declaration(now_value)}\n    \#{TOKEN_BUCKET_ALGORITHM_BODY}\n  LUA\nend\n".freeze