- ACQUIRE_READ =
KEYS = writer_key, KEYS = readers_key ARGV = token, ARGV = expiry (unix ts), ARGV = now (unix ts) Returns 1 = acquired, 0 = blocked
<<~LUA.freeze
local writer_key = KEYS[1]
local readers_key = KEYS[2]
local token = ARGV[1]
local expiry = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
redis.call('ZREMRANGEBYSCORE', readers_key, '-inf', now)
if redis.call('EXISTS', writer_key) == 1 then
return 0
end
redis.call('ZADD', readers_key, expiry, token)
local current_ttl = redis.call('TTL', readers_key)
if current_ttl == -1 or (current_ttl > 0 and (now + current_ttl) < expiry) then
redis.call('EXPIREAT', readers_key, expiry + 1)
end
return 1
LUA
- RELEASE_READ =
<<~LUA.freeze
redis.call('ZREM', KEYS[1], ARGV[1])
return 1
LUA
- ACQUIRE_WRITE =
KEYS = writer_key, KEYS = readers_key ARGV = token, ARGV = ttl (seconds), ARGV = now (unix ts) Returns 1 = acquired, 0 = blocked
<<~LUA.freeze
local writer_key = KEYS[1]
local readers_key = KEYS[2]
local token = ARGV[1]
local ttl = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
redis.call('ZREMRANGEBYSCORE', readers_key, '-inf', now)
if redis.call('ZCARD', readers_key) > 0 then
return 0
end
if redis.call('EXISTS', writer_key) == 1 then
return 0
end
redis.call('SET', writer_key, token, 'EX', ttl)
return 1
LUA
- RELEASE_WRITE =
KEYS = writer_key ARGV = token Returns 1 = released, 0 = not owner
<<~LUA.freeze
if redis.call('GET', KEYS[1]) == ARGV[1] then
redis.call('DEL', KEYS[1])
return 1
end
return 0
LUA