Last active
August 29, 2015 14:27
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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