RemoteStore: Add option to drop old connections from the pool

This is a hack to make hydra-queue-runner free its temproots
periodically, thereby ensuring that garbage collection of the
corresponding paths is not blocked until the queue runner is
restarted.

It would be better if temproots could be released earlier than at
process exit. I started working on a RAII object returned by functions
like addToStore() that releases temproots. However, this would be a
pretty massive change so I gave up on it for now.
This commit is contained in:
Eelco Dolstra 2017-09-14 18:10:38 +02:00
parent 308ecf6361
commit 89dc62c174
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
3 changed files with 31 additions and 1 deletions

View file

@ -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 {

View file

@ -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();

View file

@ -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);
}
};
}