diff --git a/dbms/src/Common/ZooKeeper/ZooKeeper.cpp b/dbms/src/Common/ZooKeeper/ZooKeeper.cpp index c3696d54ffa..bccfd16b61c 100644 --- a/dbms/src/Common/ZooKeeper/ZooKeeper.cpp +++ b/dbms/src/Common/ZooKeeper/ZooKeeper.cpp @@ -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; +} - auto callback = [&](const ZooKeeperImpl::ZooKeeper::ExistsResponse & response) +void ZooKeeper::waitForDisappear(const std::string & path) +{ + WaitForDisappearStatePtr state = std::make_shared(); + + 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; } } diff --git a/dbms/src/Common/ZooKeeper/ZooKeeperImpl.cpp b/dbms/src/Common/ZooKeeper/ZooKeeperImpl.cpp index 079df186c17..cbd229c0b81 100644 --- a/dbms/src/Common/ZooKeeper/ZooKeeperImpl.cpp +++ b/dbms/src/Common/ZooKeeper/ZooKeeperImpl.cpp @@ -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)