ClickHouse/libs/libzkutil/include/zkutil/Lock.h

81 lines
2.5 KiB
C++
Raw Normal View History

#pragma once
#include <zkutil/ZooKeeperHolder.h>
2015-09-29 19:19:54 +00:00
#include <common/logger_useful.h>
2015-10-05 01:35:28 +00:00
#include <DB/Common/Exception.h>
namespace zkutil
{
class Lock
{
public:
/// lock_prefix - относительный путь до блокировки в ZK. Начинается со слеша
/// lock_name - имя ноды блокировки в ZK
Lock(
zkutil::ZooKeeperHolderPtr zookeeper_holder_,
const std::string & lock_prefix_,
const std::string & lock_name_,
const std::string & lock_message_ = "",
bool create_parent_path_ = false)
:
zookeeper_holder(zookeeper_holder_),
lock_path(lock_prefix_ + "/" + lock_name_),
lock_message(lock_message_),
log(&Logger::get("zkutil::Lock"))
{
auto zookeeper = zookeeper_holder->getZooKeeper();
if (create_parent_path_)
zookeeper->createAncestors(lock_prefix_);
zookeeper->createIfNotExists(lock_prefix_, "");
}
Lock(const Lock &) = delete;
Lock(Lock && lock) = default;
Lock & operator=(const Lock &) = delete;
~Lock()
{
try
{
unlock();
}
catch (const zkutil::KeeperException & e)
{
DB::tryLogCurrentException(__PRETTY_FUNCTION__);
}
}
enum Status
{
UNLOCKED,
LOCKED_BY_ME,
LOCKED_BY_OTHER,
END
};
std::string status2String(Status status);
/// проверяет создана ли эфемерная нода и кто ее владелец.
Status tryCheck() const;
void unlock();
void unlockOrMoveIfFailed(std::vector<zkutil::Lock> & failed_to_unlock_locks);
bool tryLock();
/// путь к ноде блокировки в zookeeper
const std::string & getPath() { return lock_path; }
private:
zkutil::ZooKeeperHolderPtr zookeeper_holder;
/// пока храним указатель на хендлер, никто не может переиницализировать сессию с zookeeper
using ZooKeeperHandler = zkutil::ZooKeeperHolder::UnstorableZookeeperHandler;
std::unique_ptr<ZooKeeperHandler> locked;
std::string lock_path;
std::string lock_message;
Logger * log;
};
}