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