andymccurdy/redis-py — pull request #411 by chillipino (2013-12-15 23:13:01+00:00)
Title: use random string tokens in LuaLock

this pull request is based on #405 from @natict addressing the issues from comments. since it looks like he hasn't had time to respond to those comments, i made changes based on his implementation; apologies to the community if doing this is frowned upon or if there's a better way (his changeset is in this pull request, so merging this would obviate #405). i saw the comment in #408 saying #405 would get merged in, but i haven't seen a commit for that yet, feel free to close this if you're already done.

the main thing this patch changes from @natict's implementation is to store a random token rather than the floating point value of the client machine's clock in string form, as ```Lock``` currently does. one invariant goes away as a side effect - after a release, ```token``` in the ```LuaLock``` instance keeps its previous value, rather than being set to ```None``` as ```Lock``` does to ```acquired_until```. i couldn't find a good way to keep that behavior since the script is effectively atomic - adding a pipeline to ```release()``` would probably work, but i chose to keep the code simple for now.

feedback welcome on everything, but i'd specifically like comments about the ```redis.client.generate_random_token()``` function - there may be better/more desirable ways to do this.

i didn't touch any of the context manager stuff, so the changes in #408 would need to be duplicated in LuaLock.

each lock implementation has its own test suite now, and both are always run. i didn't do anything special if the redis server being used is pre-2.6 - ```LuaLock``` tests will always fail in that case. i'm not sure what you target for automated tests, so this may need some touchups.

for both ```Lock``` and ```LuaLock```, it appears to be possible to incorrectly release a lock that has a timeout when sharing a lock instance within a single process. i need to set up a test case to confirm this, and if it does happen, i'll open a separate issue to propose a solution.