diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 1af84cff5ba834f068bc9941114183a10c595740..b9076c0474d6beec4f67c618b4d386351b65cf9c 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -45,7 +45,13 @@ RemoteStore::RemoteStore(const Params & params) , connections(make_ref<Pool<Connection>>( std::max(1, (int) maxConnections), [this]() { return openConnectionWrapper(); }, - [](const ref<Connection> & r) { return r->to.good() && r->from.good(); } + [this](const ref<Connection> & r) { + return + r->to.good() + && r->from.good() + && std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::steady_clock::now() - r->startTime).count() < maxConnectionAge; + } )) { } @@ -106,6 +112,8 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection() conn->from.fd = conn->fd.get(); conn->to.fd = conn->fd.get(); + conn->startTime = std::chrono::steady_clock::now(); + initConnection(*conn); return conn; @@ -619,6 +627,12 @@ void RemoteStore::connect() } +void RemoteStore::flushBadConnections() +{ + connections->flushBad(); +} + + RemoteStore::Connection::~Connection() { try { diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index e370e4797d24f1142e45087f9177dd6a21184ca2..30c6beae6ff2e0d74c6ca9216fef46d5b6e9e5d1 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -25,6 +25,9 @@ public: const Setting<int> maxConnections{(Store*) this, 1, "max-connections", "maximum number of concurrent connections to the Nix daemon"}; + const Setting<unsigned int> maxConnectionAge{(Store*) this, std::numeric_limits<unsigned int>::max(), + "max-connection-age", "number of seconds to reuse a connection"}; + RemoteStore(const Params & params); /* Implementations of abstract store API methods. */ @@ -95,6 +98,8 @@ public: void connect() override; + void flushBadConnections(); + protected: struct Connection @@ -102,6 +107,7 @@ protected: FdSink to; FdSource from; unsigned int daemonVersion; + std::chrono::time_point<std::chrono::steady_clock> startTime; virtual ~Connection(); diff --git a/src/libutil/pool.hh b/src/libutil/pool.hh index 7033090020ef8e384b07c554cb835b3a388a7d3a..0b142b0597c7b42732ce02a3b0911ab63cda22e2 100644 --- a/src/libutil/pool.hh +++ b/src/libutil/pool.hh @@ -168,6 +168,16 @@ public: { return state.lock()->max; } + + void flushBad() + { + auto state_(state.lock()); + std::vector<ref<R>> left; + for (auto & p : state_->idle) + if (validator(p)) + left.push_back(p); + std::swap(state_->idle, left); + } }; }