-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
199 additions
and
1 deletion.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from .base import BaseAPI | ||
|
||
|
||
class LockAPI(BaseAPI): | ||
def lock(self, name, lease=0): | ||
""" | ||
Lock acquires a distributed shared lock on a given named lock. | ||
On success, it will return a unique key that exists so long as | ||
the lock is held by the caller. This key can be used in | ||
conjunction with transactions to safely ensure updates to etcd | ||
only occur while holding lock ownership. The lock is held until | ||
Unlock is called on the key or the lease associate with the | ||
owner expires. | ||
:type name: str | ||
:param name: name is the identifier for the distributed shared lock to be acquired. | ||
:type lease: int | ||
:param lease: lease is the lease ID to associate with the key in the key-value store. A lease | ||
value of 0 indicates no lease. | ||
""" | ||
|
||
method = '/v3beta/lock/lock' | ||
data = { | ||
"name": name, | ||
"lease": lease | ||
} | ||
return self.call_rpc(method, data=data) | ||
|
||
def unlock(self, key): | ||
""" | ||
Unlock takes a key returned by Lock and releases the hold on | ||
lock. The next Lock caller waiting for the lock will then be | ||
woken up and given ownership of the lock. | ||
:type key: str | ||
:param key: key is the lock ownership key granted by Lock. | ||
:type lease: int | ||
:param lease: lease is the lease ID to associate with the key in the key-value store. A lease | ||
value of 0 indicates no lease. | ||
""" | ||
|
||
method = '/v3beta/lock/unlock' | ||
data = { | ||
"key": key, | ||
} | ||
return self.call_rpc(method, data=data) |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import time | ||
|
||
import pytest | ||
|
||
from etcd3.client import Client | ||
from tests.docker_cli import docker_run_etcd_main | ||
from .envs import protocol, host, port | ||
from .etcd_go_cli import NO_ETCD_SERVICE, etcdctl | ||
|
||
|
||
@pytest.fixture(scope='module') | ||
def client(): | ||
""" | ||
init Etcd3Client, close its connection-pool when teardown | ||
""" | ||
_, p, _ = docker_run_etcd_main() | ||
c = Client(host, p, protocol) | ||
yield c | ||
c.close() | ||
|
||
|
||
@pytest.mark.skipif(NO_ETCD_SERVICE, reason="no etcd service available") | ||
def test_hash(client): | ||
assert client.hash().hash | ||
|
||
|
||
@pytest.mark.skipif(NO_ETCD_SERVICE, reason="no etcd service available") | ||
def test_lock_flow(client): | ||
lease1 = client.Lease(5) | ||
lease1.grant() | ||
lock1 = client.lock('test_lock', lease1._ID) | ||
assert lock1.key.startswith(b'test_lock/') | ||
|
||
lease2 = client.Lease(15) | ||
lease2.grant() | ||
start_lock_ts = time.time() | ||
client.lock('test_lock', lease2._ID) | ||
assert (time.time() - start_lock_ts) > 3 | ||
|
||
lease2.revoke() | ||
|
||
lease3 = client.Lease(5) | ||
lease3.grant() | ||
start_lock_ts = time.time() | ||
lock3 = client.lock('test_lock', lease3._ID) | ||
assert (time.time() - start_lock_ts) < 2 | ||
|
||
client.unlock(lock3.key) |