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:
Eelco Dolstra 2017-04-06 18:40:19 +02:00
parent 963f2bf12b
commit ba20730b3f
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 44 additions and 3 deletions

View file

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

View file

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

View file

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

View file

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

View file

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