Created
April 12, 2016 00:16
-
-
Save wolever/283c1a7698fdba3a191faccd714bfad8 to your computer and use it in GitHub Desktop.
Because sometimes you just need a spinlock
This file contains 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
@contextmanager | |
def spinlock(key, suffix=":lock", duration=1, spinsleep=0.01): | |
""" A simple Redis-based spinlock for situations where pessimistic locking | |
makes life simpler, and the chance of collisions is low enough that | |
a spinlock is a reasonable tradeoff. | |
The lock is held for at most ``duration`` seconds (after which it's | |
ignored), and polled every ``spinsleep`` seconds. | |
For example:: | |
with spinlock("my-key"): | |
print "lock held on my-key" | |
""" | |
end_time = time.time() + duration | |
lock_key = "%s%s" %(key, suffix) | |
with get_redis_connection() as cxn: | |
while True: | |
if time.time() > end_time: | |
break | |
first = cxn.set(lock_key, "held", nx=True, ex=duration) | |
if first: | |
break | |
time.sleep(spinsleep) | |
try: | |
yield cxn | |
finally: | |
cxn.delete(lock_key) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment