about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/remote-store.cc16
-rw-r--r--src/libstore/remote-store.hh6
-rw-r--r--src/libutil/pool.hh10
3 files changed, 31 insertions, 1 deletions
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 1af84cff5ba8..b9076c0474d6 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 e370e4797d24..30c6beae6ff2 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 7033090020ef..0b142b0597c7 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);
+    }
 };
 
 }