From c82b67fa05a161600b264347321dfda618c79efc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 10 Aug 2025 17:48:19 +0200 Subject: [PATCH] BasicClientConnection::queryPathInfo(): Don't throw exception for invalid paths This caused RemoteStore::queryPathInfoUncached() to mark the connection as invalid (see RemoteStore::ConnectionHandle::~ConnectionHandle()), causing it to disconnect and reconnect after every lookup of an invalid path. This caused huge slowdowns in conjunction with 19f89eb6842747570f262c003d977f02cb155968 and lazy-trees. --- .../include/nix/store/worker-protocol-connection.hh | 3 ++- src/libstore/remote-store.cc | 13 +++++++------ src/libstore/worker-protocol-connection.cc | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/libstore/include/nix/store/worker-protocol-connection.hh b/src/libstore/include/nix/store/worker-protocol-connection.hh index f7ddfea4f..73dd50719 100644 --- a/src/libstore/include/nix/store/worker-protocol-connection.hh +++ b/src/libstore/include/nix/store/worker-protocol-connection.hh @@ -109,7 +109,8 @@ struct WorkerProto::BasicClientConnection : WorkerProto::BasicConnection const StorePathSet & paths, SubstituteFlag maybeSubstitute); - UnkeyedValidPathInfo queryPathInfo(const StoreDirConfig & store, bool * daemonException, const StorePath & path); + std::optional + queryPathInfo(const StoreDirConfig & store, bool * daemonException, const StorePath & path); void putBuildDerivationRequest( const StoreDirConfig & store, diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index d3446093d..8c2f268c3 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -259,13 +259,14 @@ void RemoteStore::queryPathInfoUncached( const StorePath & path, Callback> callback) noexcept { try { - std::shared_ptr info; - { + auto info = ({ auto conn(getConnection()); - info = std::make_shared( - StorePath{path}, conn->queryPathInfo(*this, &conn.daemonException, path)); - } - callback(std::move(info)); + conn->queryPathInfo(*this, &conn.daemonException, path); + }); + if (!info) + callback(nullptr); + else + callback(std::make_shared(StorePath{path}, *info)); } catch (...) { callback.rethrow(); } diff --git a/src/libstore/worker-protocol-connection.cc b/src/libstore/worker-protocol-connection.cc index 015a79ad6..987d0c8dd 100644 --- a/src/libstore/worker-protocol-connection.cc +++ b/src/libstore/worker-protocol-connection.cc @@ -244,7 +244,7 @@ void WorkerProto::BasicServerConnection::postHandshake(const StoreDirConfig & st WorkerProto::write(store, *this, info); } -UnkeyedValidPathInfo WorkerProto::BasicClientConnection::queryPathInfo( +std::optional WorkerProto::BasicClientConnection::queryPathInfo( const StoreDirConfig & store, bool * daemonException, const StorePath & path) { to << WorkerProto::Op::QueryPathInfo << store.printStorePath(path); @@ -253,14 +253,14 @@ UnkeyedValidPathInfo WorkerProto::BasicClientConnection::queryPathInfo( } catch (Error & e) { // Ugly backwards compatibility hack. if (e.msg().find("is not valid") != std::string::npos) - throw InvalidPath(std::move(e.info())); + return std::nullopt; throw; } if (GET_PROTOCOL_MINOR(protoVersion) >= 17) { bool valid; from >> valid; if (!valid) - throw InvalidPath("path '%s' is not valid", store.printStorePath(path)); + return std::nullopt; } return WorkerProto::Serialise::read(store, *this); }