1 | #include "KeeperException.h" |
---|---|
2 | #include "Lock.h" |
3 | |
4 | |
5 | using namespace zkutil; |
6 | |
7 | bool Lock::tryLock() |
8 | { |
9 | auto zookeeper = zookeeper_holder->getZooKeeper(); |
10 | if (locked) |
11 | { |
12 | /// проверим, что нода создана и я ее владелец |
13 | if (tryCheck() != Status::LOCKED_BY_ME) |
14 | locked.reset(nullptr); |
15 | } |
16 | else |
17 | { |
18 | std::string dummy; |
19 | int32_t code = zookeeper->tryCreate(lock_path, lock_message, zkutil::CreateMode::Ephemeral, dummy); |
20 | |
21 | if (code == Coordination::ZNODEEXISTS) |
22 | { |
23 | locked.reset(nullptr); |
24 | } |
25 | else if (code == Coordination::ZOK) |
26 | { |
27 | locked.reset(new ZooKeeperHandler(zookeeper)); |
28 | } |
29 | else |
30 | { |
31 | throw Coordination::Exception(code); |
32 | } |
33 | } |
34 | return bool(locked); |
35 | } |
36 | |
37 | void Lock::unlock() |
38 | { |
39 | if (locked) |
40 | { |
41 | auto zookeeper = zookeeper_holder->getZooKeeper(); |
42 | if (tryCheck() == Status::LOCKED_BY_ME) |
43 | zookeeper->remove(lock_path, -1); |
44 | locked.reset(nullptr); |
45 | } |
46 | } |
47 | |
48 | Lock::Status Lock::tryCheck() const |
49 | { |
50 | auto zookeeper = zookeeper_holder->getZooKeeper(); |
51 | |
52 | Status lock_status; |
53 | Coordination::Stat stat; |
54 | std::string dummy; |
55 | bool result = zookeeper->tryGet(lock_path, dummy, &stat); |
56 | if (!result) |
57 | lock_status = UNLOCKED; |
58 | else |
59 | { |
60 | if (stat.ephemeralOwner == zookeeper->getClientID()) |
61 | lock_status = LOCKED_BY_ME; |
62 | else |
63 | lock_status = LOCKED_BY_OTHER; |
64 | } |
65 | |
66 | if (locked && lock_status != LOCKED_BY_ME) |
67 | LOG_WARNING(log, "Lock is lost. It is normal if session was expired. Path: "<< lock_path << "/"<< lock_message); |
68 | |
69 | return lock_status; |
70 | } |
71 | |
72 | void Lock::unlockAssumeLockNodeRemovedManually() |
73 | { |
74 | locked.reset(nullptr); |
75 | } |
76 | |
77 |