bucket-limiter 0.2.0

Token bucket like limiter library based on redis storage
Documentation

local effects = {}
for idx, key in ipairs(KEYS) do
  local idxBase = (idx - 1) * 5
  local interval = tonumber(ARGV[idxBase + 1])
  local capacity = tonumber(ARGV[idxBase + 2])
  local nTokens = tonumber(ARGV[idxBase + 3])
  local timeNow = tonumber(ARGV[idxBase + 4])
  local expire = tonumber(ARGV[idxBase + 5])
  local currentTokens = -1
  local lastFillAt = timeNow

  if redis.call('exists', key) == 0 then
    currentTokens = capacity
    redis.call('hset', key, 'lastFillAt', timeNow)
  else
    lastFillAt = tonumber(redis.call('hget', key, 'lastFillAt'))
    if timeNow - lastFillAt > interval then
      currentTokens = capacity
      redis.call('hset', key, 'lastFillAt', timeNow)
    else
      currentTokens = tonumber(redis.call('hget', key, 'tokens'))
    end
  end

  assert(currentTokens >= 0)

  if expire > 0 then
    redis.call('expire', key, expire)
  end

  if nTokens > currentTokens then
    redis.call('hset', key, 'tokens', currentTokens)
    for i, effect in ipairs(effects) do
      redis.call('hset', effect[1], 'tokens', effect[2])
    end
    return {key, interval, capacity, currentTokens, lastFillAt}
  else
    table.insert(effects, {key, currentTokens, nTokens})
  end
end

for i, effect in ipairs(effects) do
  redis.call('hset', effect[1], 'tokens', effect[2] - effect[3])
end

return {'', 0, 0, 0, 0}