1#include "KeeperException.h"
2#include "Lock.h"
3
4
5using namespace zkutil;
6
7bool 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
37void 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
48Lock::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
72void Lock::unlockAssumeLockNodeRemovedManually()
73{
74 locked.reset(nullptr);
75}
76
77