Skip to content

Commit

Permalink
Implement RemoteStore::queryMissing()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
edolstra committed Apr 6, 2017
1 parent 963f2bf commit ba20730
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
25 changes: 25 additions & 0 deletions src/libstore/remote-store.cc
Expand Up @@ -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()
{
try {
Expand Down
4 changes: 4 additions & 0 deletions src/libstore/remote-store.hh
Expand Up @@ -85,6 +85,10 @@ public:

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:

struct Connection
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/store-api.hh
Expand Up @@ -524,7 +524,7 @@ public:
/* 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
that will be substituted. */
void queryMissing(const PathSet & targets,
virtual void queryMissing(const PathSet & targets,
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
unsigned long long & downloadSize, unsigned long long & narSize);

Expand Down
5 changes: 3 additions & 2 deletions src/libstore/worker-protocol.hh
Expand Up @@ -6,7 +6,7 @@ namespace nix {
#define WORKER_MAGIC_1 0x6e697863
#define WORKER_MAGIC_2 0x6478696f

#define PROTOCOL_VERSION 0x112
#define PROTOCOL_VERSION 0x113
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)

Expand Down Expand Up @@ -47,7 +47,8 @@ typedef enum {
wopBuildDerivation = 36,
wopAddSignatures = 37,
wopNarFromPath = 38,
wopAddToStoreNar = 39
wopAddToStoreNar = 39,
wopQueryMissing = 40,
} WorkerOp;


Expand Down
11 changes: 11 additions & 0 deletions src/nix-daemon/nix-daemon.cc
Expand Up @@ -592,6 +592,17 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
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:
throw Error(format("invalid operation %1%") % op);
}
Expand Down

0 comments on commit ba20730

Please sign in to comment.