ClickHouse/dbms/Common/ZooKeeper/ZooKeeperHolder.h

87 lines
2.8 KiB
C++
Raw Normal View History

#pragma once
#include "ZooKeeper.h"
#include <mutex>
#include <boost/noncopyable.hpp>
namespace zkutil
{
2015-12-25 09:10:17 +00:00
class Lock;
class ZooKeeperHolder : public boost::noncopyable
{
friend class zkutil::Lock;
protected:
class UnstorableZookeeperHandler;
public:
ZooKeeperHolder() = default;
/// вызывать из одного потока - не thread safe
2017-09-15 12:16:12 +00:00
template <typename... Args>
2018-08-24 05:25:00 +00:00
void init(Args &&... args);
/// был ли класс инициализирован
bool isInitialized() const { return ptr != nullptr; }
2017-04-25 15:21:03 +00:00
/// Workaround for zkutil::Lock
void initFromInstance(const ZooKeeper::Ptr & zookeeper_ptr);
UnstorableZookeeperHandler getZooKeeper();
bool replaceZooKeeperSessionToNewOne();
bool isSessionExpired() const;
protected:
/** Хендлер для подсчета количества используемых ссылок на ZooKeeper
*
* Запрещается переинициализировать ZooKeeper пока, хранится хотя бы один хендлер на него.
* Большинство классов должны хранить хендлер на стеке и не хранить как член класса.
* Т.е. хранить holder и запрашивать хендлер перед каждым использованием.
* Поэтому класс специально объявлен, как protected.
*
* Исключение - классы, работающие с эфимерными нодами. Пример: zkutil::Lock
*
* Как использовать:
* auto zookeeper = zookeeper_holder->getZooKeeper();
* zookeeper->get(path);
*/
class UnstorableZookeeperHandler
{
public:
UnstorableZookeeperHandler(ZooKeeper::Ptr zk_ptr_);
explicit operator bool() const { return bool(zk_ptr); }
bool operator==(std::nullptr_t) const { return zk_ptr == nullptr; }
bool operator!=(std::nullptr_t) const { return !(*this == nullptr); }
/// в случае nullptr методы разыменования кидают исключение,
/// с более подробным текстом, чем просто nullptr
ZooKeeper * operator->();
const ZooKeeper * operator->() const;
ZooKeeper & operator*();
const ZooKeeper & operator*() const;
private:
ZooKeeper::Ptr zk_ptr;
};
private:
mutable std::mutex mutex;
ZooKeeper::Ptr ptr;
Logger * log = &Logger::get("ZooKeeperHolder");
static std::string nullptr_exception_message;
};
2017-09-15 12:16:12 +00:00
template <typename... Args>
2018-08-24 05:25:00 +00:00
void ZooKeeperHolder::init(Args &&... args)
{
ptr = std::make_shared<ZooKeeper>(std::forward<Args>(args)...);
}
using ZooKeeperHolderPtr = std::shared_ptr<ZooKeeperHolder>;
}