jplana / python-etcd

A python client for etcd
Other
520 stars 210 forks source link

Failure to acquire lock still refreshes ttl #228

Closed gabeochoa closed 7 years ago

gabeochoa commented 7 years ago
lock = etcd.Lock(client, 'my_lock')
lock.acquire(blocking=False, lock_ttl=10)
if not lock.is_acquired:
    print "we dont have lock"
else:
    print "we got lock"

This will create a lock and exit before releasing If we run it again before the original ttl expires, the check for acquire will fail, but will create a second lock but will not be released.

From here on any acquire will fail as long as the ttls haven't expired, but will create another lock so another run of the program will see that lock and fail to acquire, ad infinitum.

lavagetto commented 7 years ago

I am sorry, but I need a full repro in code terms, I'm not sure I get how to reproduce this bug.

gabeochoa commented 7 years ago

mycode.py

import etcd 

client = etcd.Client(port=2379)
lock = etcd.Lock(client, 'my_lock')
lock.acquire(blocking=False, lock_ttl=5)
if not lock.is_acquired:
    print "we dont have lock"
else:
    print "we got lock"
  1. python mycode.py, it will get a lock
  2. immediately run it again and keep launching it, it will continue to say 'we don't have lock', but will create new locks. You will see that even after 5 seconds (from the first run) the Lock does not expire

You can only get a lock if you wait 5 seconds from the most recent time you ran the program

(venv) gabe@margot[17:48:39] ~/Desktop/loans : python me.py
we got lock
(venv) gabe@margot[17:48:41] ~/Desktop/loans : python me.py
we dont have lock
(venv) gabe@margot[17:48:42] ~/Desktop/loans : python me.py
we dont have lock
(venv) gabe@margot[17:48:43] ~/Desktop/loans : python me.py
we dont have lock
(venv) gabe@margot[17:48:44] ~/Desktop/loans : python me.py
we dont have lock
(venv) gabe@margot[17:48:45] ~/Desktop/loans : python me.py
we dont have lock
(venv) gabe@margot[17:48:46] ~/Desktop/loans : python me.py
we dont have lock
(venv) gabe@margot[17:48:51] ~/Desktop/loans : python me.py
we got lock

Here you can see the time, at 17:48:39 we create the lock Even at 17:48:46 (more than 5 seconds later) we still cant acquire the lock However if we wait 5 seconds without running (from ..46 to ..51) then we can get the lock

lavagetto commented 7 years ago

You are just writing incorrect code, and that might be due to our documentation being not clear enough:

whenver you require a lock, you get into a "lock queue", so you should always release the lock even if it wasn't properly acquired; think of it as cleaning up after yourself.

so if you just add lock.release() to your code, it will work correctly.