ZooKeeper: fixed error [#CLICKHOUSE-2]

This commit is contained in:
Alexey Milovidov 2018-04-05 07:06:23 +03:00
parent 403a2c62a2
commit e00e81c3e9
2 changed files with 31 additions and 17 deletions

View File

@ -530,39 +530,53 @@ void ZooKeeper::tryRemoveRecursive(const std::string & path)
}
void ZooKeeper::waitForDisappear(const std::string & path)
namespace
{
while (true)
struct WaitForDisappearState
{
int32_t code = 0;
int32_t event_type = 0;
Poco::Event event;
};
using WaitForDisappearStatePtr = std::shared_ptr<WaitForDisappearState>;
}
auto callback = [&](const ZooKeeperImpl::ZooKeeper::ExistsResponse & response)
void ZooKeeper::waitForDisappear(const std::string & path)
{
WaitForDisappearStatePtr state = std::make_shared<WaitForDisappearState>();
while (true)
{
auto callback = [state](const ZooKeeperImpl::ZooKeeper::ExistsResponse & response)
{
code = response.error;
if (code)
event.set();
state->code = response.error;
if (state->code)
state->event.set();
};
auto watch = [&](const ZooKeeperImpl::ZooKeeper::WatchResponse & response)
auto watch = [state](const ZooKeeperImpl::ZooKeeper::WatchResponse & response)
{
code = response.error;
if (!code)
event_type = response.type;
event.set();
if (!state->code)
{
state->code = response.error;
if (!state->code)
state->event_type = response.type;
state->event.set();
}
};
/// NOTE: if the node doesn't exist, the watch will leak.
impl->exists(path, callback, watch);
event.wait();
state->event.wait();
if (code == ZooKeeperImpl::ZooKeeper::ZNONODE)
if (state->code == ZooKeeperImpl::ZooKeeper::ZNONODE)
return;
if (code)
throw KeeperException(code, path);
if (state->code)
throw KeeperException(state->code, path);
if (event_type == ZooKeeperImpl::ZooKeeper::DELETED)
if (state->event_type == ZooKeeperImpl::ZooKeeper::DELETED)
return;
}
}

View File

@ -1021,7 +1021,7 @@ void ZooKeeper::finalize(bool error_send, bool error_receive)
WatchResponse response;
response.type = SESSION;
response.state = EXPIRED_SESSION;
response.error = ZCONNECTIONLOSS;
response.error = ZSESSIONEXPIRED;
for (auto & callback : path_watches.second)
if (callback)