2014-05-27 16:59:49 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2015-12-10 14:58:13 +00:00
|
|
|
|
#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>
|
2014-05-27 16:59:49 +00:00
|
|
|
|
|
|
|
|
|
namespace zkutil
|
|
|
|
|
{
|
|
|
|
|
class Lock
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/// lock_prefix - относительный путь до блокировки в ZK. Начинается со слеша
|
|
|
|
|
/// lock_name - имя ноды блокировки в ZK
|
2015-12-10 14:58:13 +00:00
|
|
|
|
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"))
|
2014-05-27 16:59:49 +00:00
|
|
|
|
{
|
2015-12-10 14:58:13 +00:00
|
|
|
|
auto zookeeper = zookeeper_holder->getZooKeeper();
|
|
|
|
|
if (create_parent_path_)
|
2014-12-26 10:40:49 +00:00
|
|
|
|
zookeeper->createAncestors(lock_prefix_);
|
2015-12-10 14:58:13 +00:00
|
|
|
|
|
2014-07-03 17:24:17 +00:00
|
|
|
|
zookeeper->createIfNotExists(lock_prefix_, "");
|
2014-05-27 16:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-26 10:40:49 +00:00
|
|
|
|
Lock(const Lock &) = delete;
|
2016-05-17 13:56:06 +00:00
|
|
|
|
Lock(Lock && lock) = default;
|
2014-12-26 10:40:49 +00:00
|
|
|
|
Lock & operator=(const Lock &) = delete;
|
|
|
|
|
|
2014-05-27 16:59:49 +00:00
|
|
|
|
~Lock()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
unlock();
|
|
|
|
|
}
|
|
|
|
|
catch (const zkutil::KeeperException & e)
|
|
|
|
|
{
|
|
|
|
|
DB::tryLogCurrentException(__PRETTY_FUNCTION__);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum Status
|
|
|
|
|
{
|
|
|
|
|
UNLOCKED,
|
2014-07-03 17:24:17 +00:00
|
|
|
|
LOCKED_BY_ME,
|
|
|
|
|
LOCKED_BY_OTHER,
|
|
|
|
|
END
|
2014-05-27 16:59:49 +00:00
|
|
|
|
};
|
2014-07-03 17:24:17 +00:00
|
|
|
|
std::string status2String(Status status);
|
2014-05-27 16:59:49 +00:00
|
|
|
|
|
2014-07-03 17:24:17 +00:00
|
|
|
|
/// проверяет создана ли эфемерная нода и кто ее владелец.
|
2015-12-14 15:29:12 +00:00
|
|
|
|
Status tryCheck() const;
|
2014-05-27 16:59:49 +00:00
|
|
|
|
|
2014-07-03 17:24:17 +00:00
|
|
|
|
void unlock();
|
2016-07-14 11:42:51 +00:00
|
|
|
|
void unlockOrMoveIfFailed(std::vector<zkutil::Lock> & failed_to_unlock_locks);
|
2014-05-27 16:59:49 +00:00
|
|
|
|
|
2014-07-03 17:24:17 +00:00
|
|
|
|
bool tryLock();
|
2014-05-27 16:59:49 +00:00
|
|
|
|
|
|
|
|
|
/// путь к ноде блокировки в zookeeper
|
|
|
|
|
const std::string & getPath() { return lock_path; }
|
|
|
|
|
|
2015-12-10 14:58:13 +00:00
|
|
|
|
private:
|
|
|
|
|
zkutil::ZooKeeperHolderPtr zookeeper_holder;
|
2015-12-18 11:22:03 +00:00
|
|
|
|
/// пока храним указатель на хендлер, никто не может переиницализировать сессию с zookeeper
|
|
|
|
|
using ZooKeeperHandler = zkutil::ZooKeeperHolder::UnstorableZookeeperHandler;
|
|
|
|
|
std::unique_ptr<ZooKeeperHandler> locked;
|
2015-12-10 14:58:13 +00:00
|
|
|
|
|
2014-05-27 16:59:49 +00:00
|
|
|
|
std::string lock_path;
|
2014-08-13 13:41:08 +00:00
|
|
|
|
std::string lock_message;
|
2014-05-27 16:59:49 +00:00
|
|
|
|
Logger * log;
|
2015-12-18 11:22:03 +00:00
|
|
|
|
|
2014-05-27 16:59:49 +00:00
|
|
|
|
};
|
|
|
|
|
}
|