Skip to content

Instantly share code, notes, and snippets.

@dblackdblack
Created September 22, 2016 14:56
Show Gist options
  • Save dblackdblack/b0078981a5543d422e627312889cd4c2 to your computer and use it in GitHub Desktop.
Save dblackdblack/b0078981a5543d422e627312889cd4c2 to your computer and use it in GitHub Desktop.
A script which acquires uses redis to ensure exactly one server runs a process
#!/bin/bash -e
set -e
# a script which acquires an exclusive lock from a redis server
# and executes a command that needs mutual exclusion across servers
# usage:
# redis_lock.sh <lock_name> <command>
redis_server=redis.example.com
lock_name=$1 ; shift
val=$(uuid -v4)
renew_time=10 # once a second, the TTL on the lock key will be set to this number of seconds
# used to clean up locks in event of a network/system failure
function acquire() {
if test "$(redis-cli -h ${redis_server} SET locks:${lock_name} ${val} EX ${renew_time} NX)" = OK ; then
echo lock acquired
else
echo unable to acquire lock
exit 1
fi
}
function renew() {
parent_pid=$1
if test "$(redis-cli -h ${redis_server} GET locks:${lock_name})" = $val ; then
redis-cli -h ${redis_server} EXPIRE locks:${lock_name} ${renew_time}
else
echo "ERROR!!! unexpexted value for lock. Someone else acquired it!!!" > /dev/fd/2
kill $parent_pid
exit 1
fi
}
function release() {
if test "$(redis-cli -h ${redis_server} GET locks:${lock_name})" = $val ; then
redis-cli -h ${redis_server} DEL locks:${lock_name}
else
echo "ERROR!!! unexpexted value for lock. Someone else acquired it!!!" > /dev/fd/2
exit 1
fi
}
function term() {
kill %1 || /bin/true
kill %2 || /bin/true
release
}
acquire
(while true ; do renew $$ ; sleep 1 ; done) &>/dev/null & # spawn a lock renewal process
trap "term" TERM INT HUP
$* & # run the desired command in the background as %2
wait %2
term
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment