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
					
				
					 5 changed files with 44 additions and 3 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue