Skip to content

Instantly share code, notes, and snippets.

@andrhamm
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrhamm/c4de5820cd686f40d55f to your computer and use it in GitHub Desktop.
Save andrhamm/c4de5820cd686f40d55f to your computer and use it in GitHub Desktop.
Redis LUA script for atomically setting a key's expiration if its value is unchanged
# EXPIREEQ key value_assertion seconds
# Set a timeout on key if the current value equals value_assertion.
# EXPIREEQ is short for "EXPIRE if EQual"
# The lua script:
expireeq = <<-EOF
local key = KEYS[1]
local val_assert = ARGV[1]
local ex = ARGV[2]
local val = redis.call("GET", key)
if val == val_assert then
return redis.call("EXPIRE", key, ex)
end
return 0
EOF
# usage with redis-rb:
# redis.eval expireeq, keys: [key], argv: [value_assert, seconds]
# Use case:
# A worker grabs a lock for processing a partition of a queue:
worker_name = "andrew"
if redis.set("queue-partition-1", worker_name, ex: 5.minutes, nx: true)
# we got the exclusive lock
loop do
# before getting more jobs, make sure we still have the lock
abort("lost our lock!") unless redis.eval(expireeq, keys: ["queue-partition-1"], argv: [worker_name, 5.minutes])
jobs = queue.get_jobs
# process jobs that might take a long time…
end
else
# we didn't get the lock :(
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment