mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
libzkutil: added multi; many fixes. [#METR-10202]
This commit is contained in:
parent
ee9345707f
commit
3411d3db64
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <Poco/Exception.h>
|
||||
#include <zkutil/ZooKeeper.h>
|
||||
#include <zkutil/Types.h>
|
||||
|
||||
|
||||
namespace zkutil
|
||||
|
44
libs/libzkutil/include/zkutil/Types.h
Normal file
44
libs/libzkutil/include/zkutil/Types.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include <zookeeper/zookeeper.hh>
|
||||
#include <Yandex/Common.h>
|
||||
#include <boost/function.hpp>
|
||||
#include <future>
|
||||
|
||||
|
||||
namespace zkutil
|
||||
{
|
||||
|
||||
namespace zk = org::apache::zookeeper;
|
||||
namespace CreateMode = zk::CreateMode;
|
||||
namespace ReturnCode = zk::ReturnCode;
|
||||
namespace SessionState = zk::SessionState;
|
||||
namespace WatchEvent = zk::WatchEvent;
|
||||
|
||||
typedef zk::data::Stat Stat;
|
||||
typedef zk::data::ACL ACL;
|
||||
typedef zk::Op Op;
|
||||
typedef zk::OpResult OpResult;
|
||||
|
||||
typedef std::vector<ACL> ACLs;
|
||||
typedef boost::ptr_vector<Op> Ops;
|
||||
typedef boost::ptr_vector<OpResult> OpResults;
|
||||
typedef std::shared_ptr<boost::ptr_vector<OpResult> > OpResultsPtr;
|
||||
typedef std::vector<std::string> Strings;
|
||||
|
||||
typedef boost::function<void (WatchEvent::type event, SessionState::type state,
|
||||
const std::string & path)> WatchFunction;
|
||||
|
||||
struct WatchEventInfo
|
||||
{
|
||||
WatchEvent::type event;
|
||||
SessionState::type state;
|
||||
std::string path;
|
||||
|
||||
WatchEventInfo() {}
|
||||
WatchEventInfo(WatchEvent::type event_, SessionState::type state_, const std::string & path_)
|
||||
: event(event_), state(state_), path(path_) {}
|
||||
};
|
||||
|
||||
typedef std::future<WatchEventInfo> WatchFuture;
|
||||
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
#include <zookeeper/zookeeper.hh>
|
||||
#include <Yandex/Common.h>
|
||||
#include <boost/function.hpp>
|
||||
#include <future>
|
||||
#include <zkutil/Types.h>
|
||||
#include <zkutil/KeeperException.h>
|
||||
|
||||
|
||||
namespace zkutil
|
||||
@ -10,38 +8,10 @@ namespace zkutil
|
||||
|
||||
const UInt32 DEFAULT_SESSION_TIMEOUT = 30000;
|
||||
|
||||
namespace zk = org::apache::zookeeper;
|
||||
namespace CreateMode = zk::CreateMode;
|
||||
namespace ReturnCode = zk::ReturnCode;
|
||||
namespace SessionState = zk::SessionState;
|
||||
namespace WatchEvent = zk::WatchEvent;
|
||||
|
||||
typedef zk::data::Stat Stat;
|
||||
typedef zk::data::ACL ACL;
|
||||
|
||||
typedef std::vector<ACL> ACLs;
|
||||
typedef std::vector<std::string> Strings;
|
||||
|
||||
typedef boost::function<void (WatchEvent::type event, SessionState::type state,
|
||||
const std::string & path)> WatchFunction;
|
||||
|
||||
struct WatchEventInfo
|
||||
{
|
||||
WatchEvent::type event;
|
||||
SessionState::type state;
|
||||
std::string path;
|
||||
|
||||
WatchEventInfo() {}
|
||||
WatchEventInfo(WatchEvent::type event_, SessionState::type state_, const std::string & path_)
|
||||
: event(event_), state(state_), path(path_) {}
|
||||
};
|
||||
|
||||
typedef std::future<WatchEventInfo> WatchFuture;
|
||||
|
||||
/** Сессия в ZooKeeper. Интерфейс существенно отличается от обычного API ZooKeeper.
|
||||
* Вместо callback-ов для watch-ей используются std::future.
|
||||
* Методы с названиями, не начинающимися с try, бросают исключение при любой ошибке.
|
||||
* Методы с названиями, начинающимися с try, не бросают исключение только при некторых видах ошибок.
|
||||
* Методы с названиями, начинающимися с try, не бросают исключение только при перечисленных видах ошибок.
|
||||
* Например, исключение бросается в любом случае, если сессия разорвалась или если не хватает прав или ресурсов.
|
||||
*/
|
||||
class ZooKeeper
|
||||
@ -58,6 +28,8 @@ public:
|
||||
|
||||
void setDefaultACL(ACLs & acl);
|
||||
|
||||
ACLs getDefaultACL();
|
||||
|
||||
/** Создать znode. Используется ACL, выставленный вызовом setDefaultACL (по умолчанию, всем полный доступ).
|
||||
* Если что-то пошло не так, бросить исключение.
|
||||
*/
|
||||
@ -86,19 +58,41 @@ public:
|
||||
|
||||
std::string get(const std::string & path, Stat * stat, WatchFuture * watch);
|
||||
|
||||
/// Возвращает false, если нет такой ноды. При остальных ошибках бросает исключение.
|
||||
bool tryGet(const std::string & path, std::string & data, Stat * stat = nullptr, WatchFuture * watch = nullptr);
|
||||
/** Не бросает исключение при следующих ошибках:
|
||||
* - Такой ноды нет. В таком случае возвращает false.
|
||||
*/
|
||||
bool tryGet(const std::string & path, std::string & res, Stat * stat = nullptr, WatchFuture * watch = nullptr);
|
||||
|
||||
void set(const std::string & path, const std::string & data,
|
||||
int32_t version = -1, Stat * stat = nullptr);
|
||||
|
||||
/** Не бросает исключение при следующих ошибках:
|
||||
* - Такой ноды нет.
|
||||
* - У ноды другая версия.
|
||||
*/
|
||||
ReturnCode::type trySet(const std::string & path, const std::string & data,
|
||||
int32_t version = -1, Stat * stat = nullptr);
|
||||
|
||||
Strings getChildren(const std::string & path,
|
||||
Stat * stat = nullptr,
|
||||
WatchFuture * watch = nullptr);
|
||||
|
||||
/** Не бросает исключение при следующих ошибках:
|
||||
* - Такой ноды нет. В таком случае возвращает false.
|
||||
*/
|
||||
bool tryGetChildren(const std::string & path, Strings & res,
|
||||
Stat * stat = nullptr,
|
||||
WatchFuture * watch = nullptr);
|
||||
|
||||
void close();
|
||||
|
||||
boost::ptr_vector<zk::OpResult> & multi(const boost::ptr_vector<zk::Op> & ops);
|
||||
/** Транзакционно выполняет несколько операций. При любой ошибке бросает исключение.
|
||||
*/
|
||||
OpResultsPtr multi(const Ops & ops);
|
||||
|
||||
/** Бросает исключение только если какая-нибудь операция вернула "неожиданную" ошибку - такую ошибку,
|
||||
* увидев которую соответствующий метод try* бросил бы исключение. */
|
||||
OpResultsPtr tryMulti(const Ops & ops);
|
||||
|
||||
private:
|
||||
friend struct StateWatch;
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include <zkutil/ZooKeeper.h>
|
||||
#include <zkutil/KeeperException.h>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
|
||||
@ -73,6 +72,11 @@ void ZooKeeper::setDefaultACL(ACLs & acl)
|
||||
default_acl = acl;
|
||||
}
|
||||
|
||||
ACLs ZooKeeper::getDefaultACL()
|
||||
{
|
||||
return default_acl;
|
||||
}
|
||||
|
||||
Strings ZooKeeper::getChildren(
|
||||
const std::string & path, Stat * stat, WatchFuture * watch)
|
||||
{
|
||||
@ -84,6 +88,21 @@ Strings ZooKeeper::getChildren(
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ZooKeeper::tryGetChildren(const std::string & path, Strings & res,
|
||||
Stat * stat, WatchFuture * watch)
|
||||
{
|
||||
Stat s;
|
||||
ReturnCode::type code = impl.getChildren(path, watchForFuture(watch), res, s);
|
||||
if (!( code == ReturnCode::Ok ||
|
||||
code == ReturnCode::NoNode))
|
||||
throw KeeperException(code);
|
||||
if (code == ReturnCode::NoNode)
|
||||
return false;
|
||||
if (stat)
|
||||
*stat = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ZooKeeper::create(const std::string & path, const std::string & data, CreateMode::type mode)
|
||||
{
|
||||
std::string res;
|
||||
@ -98,8 +117,8 @@ ReturnCode::type ZooKeeper::tryCreate(const std::string & path, const std::strin
|
||||
code == ReturnCode::NoNode ||
|
||||
code == ReturnCode::NodeExists ||
|
||||
code == ReturnCode::NoChildrenForEphemerals))
|
||||
return code;
|
||||
throw KeeperException(code);
|
||||
throw KeeperException(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
void ZooKeeper::remove(const std::string & path, int32_t version)
|
||||
@ -107,11 +126,6 @@ void ZooKeeper::remove(const std::string & path, int32_t version)
|
||||
CHECKED(impl.remove(path, version));
|
||||
}
|
||||
|
||||
/** Не бросает исключение при следующих ошибках:
|
||||
* - Такой ноды нет.
|
||||
* - У ноды другая версия.
|
||||
* - У ноды есть дети.
|
||||
*/
|
||||
ReturnCode::type ZooKeeper::tryRemove(const std::string & path, int32_t version)
|
||||
{
|
||||
ReturnCode::type code = impl.remove(path, version);
|
||||
@ -119,19 +133,22 @@ ReturnCode::type ZooKeeper::tryRemove(const std::string & path, int32_t version)
|
||||
code == ReturnCode::NoNode ||
|
||||
code == ReturnCode::BadVersion ||
|
||||
code == ReturnCode::NotEmpty))
|
||||
return code;
|
||||
throw KeeperException(code);
|
||||
throw KeeperException(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
bool ZooKeeper::exists(const std::string & path, Stat * stat, WatchFuture * watch)
|
||||
{
|
||||
Stat s;
|
||||
ReturnCode::type code = impl.exists(path, watchForFuture(watch), s);
|
||||
if (code != ReturnCode::Ok && code != ReturnCode::NoNode)
|
||||
if (!( code == ReturnCode::Ok ||
|
||||
code == ReturnCode::NoNode))
|
||||
throw KeeperException(code);
|
||||
if (code == ReturnCode::NoNode)
|
||||
return false;
|
||||
if (stat)
|
||||
*stat = s;
|
||||
return code == ReturnCode::Ok;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ZooKeeper::get(const std::string & path, Stat * stat, WatchFuture * watch)
|
||||
@ -144,10 +161,13 @@ std::string ZooKeeper::get(const std::string & path, Stat * stat, WatchFuture *
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ZooKeeper::tryGet(const std::string & path, std::string & data, Stat * stat, WatchFuture * watch)
|
||||
bool ZooKeeper::tryGet(const std::string & path, std::string & res, Stat * stat, WatchFuture * watch)
|
||||
{
|
||||
Stat s;
|
||||
ReturnCode::type code = impl.get(path, watchForFuture(watch), data, s);
|
||||
ReturnCode::type code = impl.get(path, watchForFuture(watch), res, s);
|
||||
if (!( code == ReturnCode::Ok ||
|
||||
code == ReturnCode::NoNode))
|
||||
throw KeeperException(code);
|
||||
if (code == ReturnCode::NoNode)
|
||||
return false;
|
||||
if (stat)
|
||||
@ -163,6 +183,71 @@ void ZooKeeper::set(const std::string & path, const std::string & data, int32_t
|
||||
*stat = s;
|
||||
}
|
||||
|
||||
ReturnCode::type ZooKeeper::trySet(const std::string & path, const std::string & data,
|
||||
int32_t version, Stat * stat)
|
||||
{
|
||||
Stat s;
|
||||
ReturnCode::type code = impl.set(path, data, version, s);
|
||||
if (!( code == ReturnCode::Ok ||
|
||||
code == ReturnCode::NoNode ||
|
||||
code == ReturnCode::BadVersion))
|
||||
throw KeeperException(code);
|
||||
if (stat)
|
||||
*stat = s;
|
||||
return code;
|
||||
}
|
||||
|
||||
OpResultsPtr ZooKeeper::multi(const Ops & ops)
|
||||
{
|
||||
OpResultsPtr res = std::make_shared<OpResults>();
|
||||
CHECKED(impl.multi(ops, *res));
|
||||
for (size_t i = 0; i < res->size(); ++i)
|
||||
{
|
||||
if ((*res)[i].getReturnCode() != ReturnCode::Ok)
|
||||
throw KeeperException((*res)[i].getReturnCode());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
OpResultsPtr ZooKeeper::tryMulti(const Ops & ops)
|
||||
{
|
||||
OpResultsPtr res = std::make_shared<OpResults>();
|
||||
CHECKED(impl.multi(ops, *res));
|
||||
for (size_t i = 0; i < res->size(); ++i)
|
||||
{
|
||||
ReturnCode::type code = (*res)[i].getReturnCode();
|
||||
|
||||
if (code != ReturnCode::Ok)
|
||||
{
|
||||
bool ok = false;
|
||||
switch (ops[i].getType())
|
||||
{
|
||||
case zk::OpCode::Create:
|
||||
ok |= code == ReturnCode::NoNode;
|
||||
ok |= code == ReturnCode::NodeExists;
|
||||
ok |= code == ReturnCode::NoChildrenForEphemerals;
|
||||
break;
|
||||
case zk::OpCode::Remove:
|
||||
ok |= code == ReturnCode::NoNode;
|
||||
ok |= code == ReturnCode::BadVersion;
|
||||
ok |= code == ReturnCode::NotEmpty;
|
||||
break;
|
||||
case zk::OpCode::SetData:
|
||||
case zk::OpCode::Check:
|
||||
ok |= code == ReturnCode::NoNode;
|
||||
ok |= code == ReturnCode::BadVersion;
|
||||
break;
|
||||
default:
|
||||
throw KeeperException("Unexpected op type");
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
throw KeeperException(code);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void ZooKeeper::close()
|
||||
{
|
||||
CHECKED(impl.close());
|
||||
|
Loading…
Reference in New Issue
Block a user