mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-02 12:32:04 +00:00
Add sync support to client
This commit is contained in:
parent
560999d587
commit
367df12626
@ -92,6 +92,7 @@
|
|||||||
M(ZooKeeperSet, "") \
|
M(ZooKeeperSet, "") \
|
||||||
M(ZooKeeperMulti, "") \
|
M(ZooKeeperMulti, "") \
|
||||||
M(ZooKeeperCheck, "") \
|
M(ZooKeeperCheck, "") \
|
||||||
|
M(ZooKeeperSync, "") \
|
||||||
M(ZooKeeperClose, "") \
|
M(ZooKeeperClose, "") \
|
||||||
M(ZooKeeperWatchResponse, "") \
|
M(ZooKeeperWatchResponse, "") \
|
||||||
M(ZooKeeperUserExceptions, "") \
|
M(ZooKeeperUserExceptions, "") \
|
||||||
|
@ -144,6 +144,7 @@ void ListRequest::addRootPath(const String & root_path) { Coordination::addRootP
|
|||||||
void CheckRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
void CheckRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
||||||
void SetACLRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
void SetACLRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
||||||
void GetACLRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
void GetACLRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
||||||
|
void SyncRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); }
|
||||||
|
|
||||||
void MultiRequest::addRootPath(const String & root_path)
|
void MultiRequest::addRootPath(const String & root_path)
|
||||||
{
|
{
|
||||||
|
@ -320,6 +320,25 @@ struct CheckResponse : virtual Response
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SyncRequest : virtual Request
|
||||||
|
{
|
||||||
|
String path;
|
||||||
|
|
||||||
|
void addRootPath(const String & root_path) override;
|
||||||
|
String getPath() const override { return path; }
|
||||||
|
|
||||||
|
size_t bytesSize() const override { return path.size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SyncResponse : virtual Response
|
||||||
|
{
|
||||||
|
String path;
|
||||||
|
|
||||||
|
size_t bytesSize() const override { return path.size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct MultiRequest : virtual Request
|
struct MultiRequest : virtual Request
|
||||||
{
|
{
|
||||||
Requests requests;
|
Requests requests;
|
||||||
@ -364,6 +383,7 @@ using GetCallback = std::function<void(const GetResponse &)>;
|
|||||||
using SetCallback = std::function<void(const SetResponse &)>;
|
using SetCallback = std::function<void(const SetResponse &)>;
|
||||||
using ListCallback = std::function<void(const ListResponse &)>;
|
using ListCallback = std::function<void(const ListResponse &)>;
|
||||||
using CheckCallback = std::function<void(const CheckResponse &)>;
|
using CheckCallback = std::function<void(const CheckResponse &)>;
|
||||||
|
using SyncCallback = std::function<void(const SyncResponse &)>;
|
||||||
using MultiCallback = std::function<void(const MultiResponse &)>;
|
using MultiCallback = std::function<void(const MultiResponse &)>;
|
||||||
|
|
||||||
|
|
||||||
@ -482,6 +502,10 @@ public:
|
|||||||
int32_t version,
|
int32_t version,
|
||||||
CheckCallback callback) = 0;
|
CheckCallback callback) = 0;
|
||||||
|
|
||||||
|
virtual void sync(
|
||||||
|
const String & path,
|
||||||
|
SyncCallback callback) = 0;
|
||||||
|
|
||||||
virtual void multi(
|
virtual void multi(
|
||||||
const Requests & requests,
|
const Requests & requests,
|
||||||
MultiCallback callback) = 0;
|
MultiCallback callback) = 0;
|
||||||
|
@ -133,6 +133,14 @@ struct TestKeeperCheckRequest final : CheckRequest, TestKeeperRequest
|
|||||||
std::pair<ResponsePtr, Undo> process(TestKeeper::Container & container, int64_t zxid) const override;
|
std::pair<ResponsePtr, Undo> process(TestKeeper::Container & container, int64_t zxid) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TestKeeperSyncRequest final : SyncRequest, TestKeeperRequest
|
||||||
|
{
|
||||||
|
TestKeeperSyncRequest() = default;
|
||||||
|
explicit TestKeeperSyncRequest(const SyncRequest & base) : SyncRequest(base) {}
|
||||||
|
ResponsePtr createResponse() const override;
|
||||||
|
std::pair<ResponsePtr, Undo> process(TestKeeper::Container & container, int64_t zxid) const override;
|
||||||
|
};
|
||||||
|
|
||||||
struct TestKeeperMultiRequest final : MultiRequest, TestKeeperRequest
|
struct TestKeeperMultiRequest final : MultiRequest, TestKeeperRequest
|
||||||
{
|
{
|
||||||
explicit TestKeeperMultiRequest(const Requests & generic_requests)
|
explicit TestKeeperMultiRequest(const Requests & generic_requests)
|
||||||
@ -413,6 +421,14 @@ std::pair<ResponsePtr, Undo> TestKeeperCheckRequest::process(TestKeeper::Contain
|
|||||||
return { std::make_shared<CheckResponse>(response), {} };
|
return { std::make_shared<CheckResponse>(response), {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<ResponsePtr, Undo> TestKeeperSyncRequest::process(TestKeeper::Container & /*container*/, int64_t) const
|
||||||
|
{
|
||||||
|
SyncResponse response;
|
||||||
|
response.path = path;
|
||||||
|
|
||||||
|
return { std::make_shared<SyncResponse>(std::move(response)), {} };
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<ResponsePtr, Undo> TestKeeperMultiRequest::process(TestKeeper::Container & container, int64_t zxid) const
|
std::pair<ResponsePtr, Undo> TestKeeperMultiRequest::process(TestKeeper::Container & container, int64_t zxid) const
|
||||||
{
|
{
|
||||||
MultiResponse response;
|
MultiResponse response;
|
||||||
@ -471,6 +487,7 @@ ResponsePtr TestKeeperGetRequest::createResponse() const { return std::make_shar
|
|||||||
ResponsePtr TestKeeperSetRequest::createResponse() const { return std::make_shared<SetResponse>(); }
|
ResponsePtr TestKeeperSetRequest::createResponse() const { return std::make_shared<SetResponse>(); }
|
||||||
ResponsePtr TestKeeperListRequest::createResponse() const { return std::make_shared<ListResponse>(); }
|
ResponsePtr TestKeeperListRequest::createResponse() const { return std::make_shared<ListResponse>(); }
|
||||||
ResponsePtr TestKeeperCheckRequest::createResponse() const { return std::make_shared<CheckResponse>(); }
|
ResponsePtr TestKeeperCheckRequest::createResponse() const { return std::make_shared<CheckResponse>(); }
|
||||||
|
ResponsePtr TestKeeperSyncRequest::createResponse() const { return std::make_shared<SyncResponse>(); }
|
||||||
ResponsePtr TestKeeperMultiRequest::createResponse() const { return std::make_shared<MultiResponse>(); }
|
ResponsePtr TestKeeperMultiRequest::createResponse() const { return std::make_shared<MultiResponse>(); }
|
||||||
|
|
||||||
|
|
||||||
@ -779,6 +796,19 @@ void TestKeeper::check(
|
|||||||
pushRequest(std::move(request_info));
|
pushRequest(std::move(request_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestKeeper::sync(
|
||||||
|
const String & path,
|
||||||
|
SyncCallback callback)
|
||||||
|
{
|
||||||
|
TestKeeperSyncRequest request;
|
||||||
|
request.path = path;
|
||||||
|
|
||||||
|
RequestInfo request_info;
|
||||||
|
request_info.request = std::make_shared<TestKeeperSyncRequest>(std::move(request));
|
||||||
|
request_info.callback = [callback](const Response & response) { callback(dynamic_cast<const SyncResponse &>(response)); };
|
||||||
|
pushRequest(std::move(request_info));
|
||||||
|
}
|
||||||
|
|
||||||
void TestKeeper::multi(
|
void TestKeeper::multi(
|
||||||
const Requests & requests,
|
const Requests & requests,
|
||||||
MultiCallback callback)
|
MultiCallback callback)
|
||||||
|
@ -79,6 +79,10 @@ public:
|
|||||||
int32_t version,
|
int32_t version,
|
||||||
CheckCallback callback) override;
|
CheckCallback callback) override;
|
||||||
|
|
||||||
|
void sync(
|
||||||
|
const String & path,
|
||||||
|
SyncCallback callback) override;
|
||||||
|
|
||||||
void multi(
|
void multi(
|
||||||
const Requests & requests,
|
const Requests & requests,
|
||||||
MultiCallback callback) override;
|
MultiCallback callback) override;
|
||||||
|
@ -667,6 +667,34 @@ Coordination::Error ZooKeeper::tryMulti(const Coordination::Requests & requests,
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Coordination::Error ZooKeeper::syncImpl(const std::string & path, std::string & returned_path)
|
||||||
|
{
|
||||||
|
auto future_result = asyncTrySyncNoThrow(path);
|
||||||
|
|
||||||
|
if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready)
|
||||||
|
{
|
||||||
|
impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Sync), path));
|
||||||
|
return Coordination::Error::ZOPERATIONTIMEOUT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto response = future_result.get();
|
||||||
|
Coordination::Error code = response.error;
|
||||||
|
returned_path = std::move(response.path);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ZooKeeper::sync(const std::string & path)
|
||||||
|
{
|
||||||
|
std::string returned_path;
|
||||||
|
check(syncImpl(path, returned_path), path);
|
||||||
|
return returned_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
Coordination::Error ZooKeeper::trySync(const std::string & path, std::string & returned_path)
|
||||||
|
{
|
||||||
|
return syncImpl(path, returned_path);
|
||||||
|
}
|
||||||
|
|
||||||
void ZooKeeper::removeChildren(const std::string & path)
|
void ZooKeeper::removeChildren(const std::string & path)
|
||||||
{
|
{
|
||||||
@ -1144,6 +1172,37 @@ Coordination::Error ZooKeeper::tryMultiNoThrow(const Coordination::Requests & re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::future<Coordination::SyncResponse> ZooKeeper::asyncTrySyncNoThrow(const std::string & path)
|
||||||
|
{
|
||||||
|
auto promise = std::make_shared<std::promise<Coordination::SyncResponse>>();
|
||||||
|
auto future = promise->get_future();
|
||||||
|
|
||||||
|
auto callback = [promise](const Coordination::SyncResponse & response) mutable
|
||||||
|
{
|
||||||
|
promise->set_value(response);
|
||||||
|
};
|
||||||
|
|
||||||
|
impl->sync(path, std::move(callback));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::future<Coordination::SyncResponse> ZooKeeper::asyncSync(const std::string & path)
|
||||||
|
{
|
||||||
|
auto promise = std::make_shared<std::promise<Coordination::SyncResponse>>();
|
||||||
|
auto future = promise->get_future();
|
||||||
|
|
||||||
|
auto callback = [promise](const Coordination::SyncResponse & response) mutable
|
||||||
|
{
|
||||||
|
if (response.error != Coordination::Error::ZOK)
|
||||||
|
promise->set_exception(std::make_exception_ptr(KeeperException(response.error)));
|
||||||
|
else
|
||||||
|
promise->set_value(response);
|
||||||
|
};
|
||||||
|
|
||||||
|
impl->sync(path, std::move(callback));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
void ZooKeeper::finalize(const String & reason)
|
void ZooKeeper::finalize(const String & reason)
|
||||||
{
|
{
|
||||||
impl->finalize(reason);
|
impl->finalize(reason);
|
||||||
|
@ -209,6 +209,10 @@ public:
|
|||||||
/// Throws nothing (even session expired errors)
|
/// Throws nothing (even session expired errors)
|
||||||
Coordination::Error tryMultiNoThrow(const Coordination::Requests & requests, Coordination::Responses & responses);
|
Coordination::Error tryMultiNoThrow(const Coordination::Requests & requests, Coordination::Responses & responses);
|
||||||
|
|
||||||
|
std::string sync(const std::string & path);
|
||||||
|
|
||||||
|
Coordination::Error trySync(const std::string & path, std::string & returned_path);
|
||||||
|
|
||||||
Int64 getClientID();
|
Int64 getClientID();
|
||||||
|
|
||||||
/// Remove the node with the subtree. If someone concurrently adds or removes a node
|
/// Remove the node with the subtree. If someone concurrently adds or removes a node
|
||||||
@ -294,6 +298,11 @@ public:
|
|||||||
/// Like the previous one but don't throw any exceptions on future.get()
|
/// Like the previous one but don't throw any exceptions on future.get()
|
||||||
FutureMulti asyncTryMultiNoThrow(const Coordination::Requests & ops);
|
FutureMulti asyncTryMultiNoThrow(const Coordination::Requests & ops);
|
||||||
|
|
||||||
|
using FutureSync = std::future<Coordination::SyncResponse>;
|
||||||
|
FutureSync asyncSync(const std::string & path);
|
||||||
|
/// Like the previous one but don't throw any exceptions on future.get()
|
||||||
|
FutureSync asyncTrySyncNoThrow(const std::string & path);
|
||||||
|
|
||||||
/// Very specific methods introduced without following general style. Implements
|
/// Very specific methods introduced without following general style. Implements
|
||||||
/// some custom throw/no throw logic on future.get().
|
/// some custom throw/no throw logic on future.get().
|
||||||
///
|
///
|
||||||
@ -329,6 +338,7 @@ private:
|
|||||||
const std::string & path, Strings & res, Coordination::Stat * stat, Coordination::WatchCallback watch_callback);
|
const std::string & path, Strings & res, Coordination::Stat * stat, Coordination::WatchCallback watch_callback);
|
||||||
Coordination::Error multiImpl(const Coordination::Requests & requests, Coordination::Responses & responses);
|
Coordination::Error multiImpl(const Coordination::Requests & requests, Coordination::Responses & responses);
|
||||||
Coordination::Error existsImpl(const std::string & path, Coordination::Stat * stat_, Coordination::WatchCallback watch_callback);
|
Coordination::Error existsImpl(const std::string & path, Coordination::Stat * stat_, Coordination::WatchCallback watch_callback);
|
||||||
|
Coordination::Error syncImpl(const std::string & path, std::string & returned_path);
|
||||||
|
|
||||||
std::unique_ptr<Coordination::IKeeper> impl;
|
std::unique_ptr<Coordination::IKeeper> impl;
|
||||||
|
|
||||||
|
@ -106,14 +106,11 @@ struct ZooKeeperSyncRequest final : ZooKeeperRequest
|
|||||||
size_t bytesSize() const override { return ZooKeeperRequest::bytesSize() + path.size(); }
|
size_t bytesSize() const override { return ZooKeeperRequest::bytesSize() + path.size(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZooKeeperSyncResponse final : ZooKeeperResponse
|
struct ZooKeeperSyncResponse final : SyncResponse, ZooKeeperResponse
|
||||||
{
|
{
|
||||||
String path;
|
|
||||||
void readImpl(ReadBuffer & in) override;
|
void readImpl(ReadBuffer & in) override;
|
||||||
void writeImpl(WriteBuffer & out) const override;
|
void writeImpl(WriteBuffer & out) const override;
|
||||||
OpNum getOpNum() const override { return OpNum::Sync; }
|
OpNum getOpNum() const override { return OpNum::Sync; }
|
||||||
|
|
||||||
size_t bytesSize() const override { return path.size(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZooKeeperHeartbeatResponse final : ZooKeeperResponse
|
struct ZooKeeperHeartbeatResponse final : ZooKeeperResponse
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "Common/ZooKeeper/ZooKeeperCommon.h"
|
||||||
#include <Common/ZooKeeper/ZooKeeperImpl.h>
|
#include <Common/ZooKeeper/ZooKeeperImpl.h>
|
||||||
#include <Common/Exception.h>
|
#include <Common/Exception.h>
|
||||||
#include <Common/ProfileEvents.h>
|
#include <Common/ProfileEvents.h>
|
||||||
@ -31,6 +32,7 @@ namespace ProfileEvents
|
|||||||
extern const Event ZooKeeperSet;
|
extern const Event ZooKeeperSet;
|
||||||
extern const Event ZooKeeperList;
|
extern const Event ZooKeeperList;
|
||||||
extern const Event ZooKeeperCheck;
|
extern const Event ZooKeeperCheck;
|
||||||
|
extern const Event ZooKeeperSync;
|
||||||
extern const Event ZooKeeperClose;
|
extern const Event ZooKeeperClose;
|
||||||
extern const Event ZooKeeperWaitMicroseconds;
|
extern const Event ZooKeeperWaitMicroseconds;
|
||||||
extern const Event ZooKeeperBytesSent;
|
extern const Event ZooKeeperBytesSent;
|
||||||
@ -1199,6 +1201,21 @@ void ZooKeeper::check(
|
|||||||
ProfileEvents::increment(ProfileEvents::ZooKeeperCheck);
|
ProfileEvents::increment(ProfileEvents::ZooKeeperCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZooKeeper::sync(
|
||||||
|
const String & path,
|
||||||
|
SyncCallback callback)
|
||||||
|
{
|
||||||
|
ZooKeeperSyncRequest request;
|
||||||
|
request.path = path;
|
||||||
|
|
||||||
|
RequestInfo request_info;
|
||||||
|
request_info.request = std::make_shared<ZooKeeperSyncRequest>(std::move(request));
|
||||||
|
request_info.callback = [callback](const Response & response) { callback(dynamic_cast<const SyncResponse &>(response)); };
|
||||||
|
|
||||||
|
pushRequest(std::move(request_info));
|
||||||
|
ProfileEvents::increment(ProfileEvents::ZooKeeperSync);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ZooKeeper::multi(
|
void ZooKeeper::multi(
|
||||||
const Requests & requests,
|
const Requests & requests,
|
||||||
|
@ -171,6 +171,10 @@ public:
|
|||||||
int32_t version,
|
int32_t version,
|
||||||
CheckCallback callback) override;
|
CheckCallback callback) override;
|
||||||
|
|
||||||
|
void sync(
|
||||||
|
const String & path,
|
||||||
|
SyncCallback callback) override;
|
||||||
|
|
||||||
void multi(
|
void multi(
|
||||||
const Requests & requests,
|
const Requests & requests,
|
||||||
MultiCallback callback) override;
|
MultiCallback callback) override;
|
||||||
|
Loading…
Reference in New Issue
Block a user