Make RemoteStore::ConnectionHandle
part of class and expose
Will need to do subclass-specific implementations in the next commit. This isn't because there will be multiple variations of the daemon protocol (whew!) but because different clients pick and choose different parts to use.
This commit is contained in:
parent
0a30b07277
commit
13269ba93b
|
@ -1,5 +1,6 @@
|
||||||
#include "remote-store.hh"
|
#include "remote-store.hh"
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
|
#include "pool.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -94,4 +95,34 @@ struct RemoteStore::Connection
|
||||||
std::exception_ptr processStderr(Sink * sink = 0, Source * source = 0, bool flush = true);
|
std::exception_ptr processStderr(Sink * sink = 0, Source * source = 0, bool flush = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around Pool<RemoteStore::Connection>::Handle that marks
|
||||||
|
* the connection as bad (causing it to be closed) if a non-daemon
|
||||||
|
* exception is thrown before the handle is closed. Such an exception
|
||||||
|
* causes a deviation from the expected protocol and therefore a
|
||||||
|
* desynchronization between the client and daemon.
|
||||||
|
*/
|
||||||
|
struct RemoteStore::ConnectionHandle
|
||||||
|
{
|
||||||
|
Pool<RemoteStore::Connection>::Handle handle;
|
||||||
|
bool daemonException = false;
|
||||||
|
|
||||||
|
ConnectionHandle(Pool<RemoteStore::Connection>::Handle && handle)
|
||||||
|
: handle(std::move(handle))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
ConnectionHandle(ConnectionHandle && h)
|
||||||
|
: handle(std::move(h.handle))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~ConnectionHandle();
|
||||||
|
|
||||||
|
RemoteStore::Connection & operator * () { return *handle; }
|
||||||
|
RemoteStore::Connection * operator -> () { return &*handle; }
|
||||||
|
|
||||||
|
void processStderr(Sink * sink = 0, Source * source = 0, bool flush = true);
|
||||||
|
|
||||||
|
void withFramedSink(std::function<void(Sink & sink)> fun);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,49 +159,25 @@ void RemoteStore::setOptions(Connection & conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A wrapper around Pool<RemoteStore::Connection>::Handle that marks
|
RemoteStore::ConnectionHandle::~ConnectionHandle()
|
||||||
the connection as bad (causing it to be closed) if a non-daemon
|
|
||||||
exception is thrown before the handle is closed. Such an exception
|
|
||||||
causes a deviation from the expected protocol and therefore a
|
|
||||||
desynchronization between the client and daemon. */
|
|
||||||
struct ConnectionHandle
|
|
||||||
{
|
{
|
||||||
Pool<RemoteStore::Connection>::Handle handle;
|
if (!daemonException && std::uncaught_exceptions()) {
|
||||||
bool daemonException = false;
|
handle.markBad();
|
||||||
|
debug("closing daemon connection because of an exception");
|
||||||
ConnectionHandle(Pool<RemoteStore::Connection>::Handle && handle)
|
|
||||||
: handle(std::move(handle))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
ConnectionHandle(ConnectionHandle && h)
|
|
||||||
: handle(std::move(h.handle))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~ConnectionHandle()
|
|
||||||
{
|
|
||||||
if (!daemonException && std::uncaught_exceptions()) {
|
|
||||||
handle.markBad();
|
|
||||||
debug("closing daemon connection because of an exception");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RemoteStore::Connection * operator -> () { return &*handle; }
|
void RemoteStore::ConnectionHandle::processStderr(Sink * sink, Source * source, bool flush)
|
||||||
RemoteStore::Connection & operator * () { return *handle; }
|
{
|
||||||
|
auto ex = handle->processStderr(sink, source, flush);
|
||||||
void processStderr(Sink * sink = 0, Source * source = 0, bool flush = true)
|
if (ex) {
|
||||||
{
|
daemonException = true;
|
||||||
auto ex = handle->processStderr(sink, source, flush);
|
std::rethrow_exception(ex);
|
||||||
if (ex) {
|
|
||||||
daemonException = true;
|
|
||||||
std::rethrow_exception(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void withFramedSink(std::function<void(Sink & sink)> fun);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ConnectionHandle RemoteStore::getConnection()
|
RemoteStore::ConnectionHandle RemoteStore::getConnection()
|
||||||
{
|
{
|
||||||
return ConnectionHandle(connections->get());
|
return ConnectionHandle(connections->get());
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1075,7 @@ std::exception_ptr RemoteStore::Connection::processStderr(Sink * sink, Source *
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionHandle::withFramedSink(std::function<void(Sink & sink)> fun)
|
void RemoteStore::ConnectionHandle::withFramedSink(std::function<void(Sink & sink)> fun)
|
||||||
{
|
{
|
||||||
(*this)->to.flush();
|
(*this)->to.flush();
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ class Pid;
|
||||||
struct FdSink;
|
struct FdSink;
|
||||||
struct FdSource;
|
struct FdSource;
|
||||||
template<typename T> class Pool;
|
template<typename T> class Pool;
|
||||||
struct ConnectionHandle;
|
|
||||||
|
|
||||||
struct RemoteStoreConfig : virtual StoreConfig
|
struct RemoteStoreConfig : virtual StoreConfig
|
||||||
{
|
{
|
||||||
|
@ -182,6 +181,8 @@ protected:
|
||||||
|
|
||||||
void setOptions() override;
|
void setOptions() override;
|
||||||
|
|
||||||
|
struct ConnectionHandle;
|
||||||
|
|
||||||
ConnectionHandle getConnection();
|
ConnectionHandle getConnection();
|
||||||
|
|
||||||
friend struct ConnectionHandle;
|
friend struct ConnectionHandle;
|
||||||
|
@ -199,5 +200,4 @@ private:
|
||||||
std::shared_ptr<Store> evalStore);
|
std::shared_ptr<Store> evalStore);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue