forked from lix-project/lix
Implement RemoteStore::queryMissing()
This provides a significant speedup, e.g. 64 s -> 12 s for nix-build --dry-run -I nixpkgs=channel:nixos-16.03 '<nixpkgs/nixos/tests/misc.nix>' -A test on a cold local and CloudFront cache. The alternative is to use lots of concurrent daemon connections but that seems wasteful.
This commit is contained in:
parent
963f2bf12b
commit
ba20730b3f
|
@ -588,6 +588,31 @@ void RemoteStore::addSignatures(const Path & storePath, const StringSet & sigs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RemoteStore::queryMissing(const PathSet & targets,
|
||||||
|
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
||||||
|
unsigned long long & downloadSize, unsigned long long & narSize)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto conn(connections->get());
|
||||||
|
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 19)
|
||||||
|
// Don't hold the connection handle in the fallback case
|
||||||
|
// to prevent a deadlock.
|
||||||
|
goto fallback;
|
||||||
|
conn->to << wopQueryMissing << targets;
|
||||||
|
conn->processStderr();
|
||||||
|
willBuild = readStorePaths<PathSet>(*this, conn->from);
|
||||||
|
willSubstitute = readStorePaths<PathSet>(*this, conn->from);
|
||||||
|
unknown = readStorePaths<PathSet>(*this, conn->from);
|
||||||
|
conn->from >> downloadSize >> narSize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
return Store::queryMissing(targets, willBuild, willSubstitute,
|
||||||
|
unknown, downloadSize, narSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RemoteStore::Connection::~Connection()
|
RemoteStore::Connection::~Connection()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -85,6 +85,10 @@ public:
|
||||||
|
|
||||||
void addSignatures(const Path & storePath, const StringSet & sigs) override;
|
void addSignatures(const Path & storePath, const StringSet & sigs) override;
|
||||||
|
|
||||||
|
void queryMissing(const PathSet & targets,
|
||||||
|
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
||||||
|
unsigned long long & downloadSize, unsigned long long & narSize) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct Connection
|
struct Connection
|
||||||
|
|
|
@ -524,7 +524,7 @@ public:
|
||||||
/* Given a set of paths that are to be built, return the set of
|
/* Given a set of paths that are to be built, return the set of
|
||||||
derivations that will be built, and the set of output paths
|
derivations that will be built, and the set of output paths
|
||||||
that will be substituted. */
|
that will be substituted. */
|
||||||
void queryMissing(const PathSet & targets,
|
virtual void queryMissing(const PathSet & targets,
|
||||||
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
|
||||||
unsigned long long & downloadSize, unsigned long long & narSize);
|
unsigned long long & downloadSize, unsigned long long & narSize);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace nix {
|
||||||
#define WORKER_MAGIC_1 0x6e697863
|
#define WORKER_MAGIC_1 0x6e697863
|
||||||
#define WORKER_MAGIC_2 0x6478696f
|
#define WORKER_MAGIC_2 0x6478696f
|
||||||
|
|
||||||
#define PROTOCOL_VERSION 0x112
|
#define PROTOCOL_VERSION 0x113
|
||||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ typedef enum {
|
||||||
wopBuildDerivation = 36,
|
wopBuildDerivation = 36,
|
||||||
wopAddSignatures = 37,
|
wopAddSignatures = 37,
|
||||||
wopNarFromPath = 38,
|
wopNarFromPath = 38,
|
||||||
wopAddToStoreNar = 39
|
wopAddToStoreNar = 39,
|
||||||
|
wopQueryMissing = 40,
|
||||||
} WorkerOp;
|
} WorkerOp;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -592,6 +592,17 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case wopQueryMissing: {
|
||||||
|
PathSet targets = readStorePaths<PathSet>(*store, from);
|
||||||
|
startWork();
|
||||||
|
PathSet willBuild, willSubstitute, unknown;
|
||||||
|
unsigned long long downloadSize, narSize;
|
||||||
|
store->queryMissing(targets, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||||
|
stopWork();
|
||||||
|
to << willBuild << willSubstitute << unknown << downloadSize << narSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Error(format("invalid operation %1%") % op);
|
throw Error(format("invalid operation %1%") % op);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue