* build.cc: only use a substituter if it returns info for a path.
This commit is contained in:
parent
5b1052663a
commit
5adbb0aabe
3 changed files with 60 additions and 54 deletions
|
@ -2187,14 +2187,34 @@ void SubstitutionGoal::init()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!worker.store.querySubstitutablePathInfo(storePath, info)) {
|
subs = substituters;
|
||||||
|
|
||||||
|
tryNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SubstitutionGoal::tryNext()
|
||||||
|
{
|
||||||
|
trace("trying next substituter");
|
||||||
|
|
||||||
|
if (subs.size() == 0) {
|
||||||
|
/* None left. Terminate this goal and let someone else deal
|
||||||
|
with it. */
|
||||||
printMsg(lvlError,
|
printMsg(lvlError,
|
||||||
format("path `%1%' is required, but there is no substituter that knows anything about it")
|
format("path `%1%' is required, but there is no substituter that can build it")
|
||||||
% storePath);
|
% storePath);
|
||||||
amDone(ecFailed);
|
amDone(ecFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub = subs.front();
|
||||||
|
subs.pop_front();
|
||||||
|
|
||||||
|
if (!worker.store.querySubstitutablePathInfo(sub, storePath, info)) {
|
||||||
|
tryNext();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* To maintain the closure invariant, we first have to realise the
|
/* To maintain the closure invariant, we first have to realise the
|
||||||
paths referenced by this one. */
|
paths referenced by this one. */
|
||||||
foreach (PathSet::iterator, i, info.references)
|
foreach (PathSet::iterator, i, info.references)
|
||||||
|
@ -2223,29 +2243,6 @@ void SubstitutionGoal::referencesValid()
|
||||||
if (*i != storePath) /* ignore self-references */
|
if (*i != storePath) /* ignore self-references */
|
||||||
assert(worker.store.isValidPath(*i));
|
assert(worker.store.isValidPath(*i));
|
||||||
|
|
||||||
subs = substituters;
|
|
||||||
|
|
||||||
tryNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SubstitutionGoal::tryNext()
|
|
||||||
{
|
|
||||||
trace("trying next substituter");
|
|
||||||
|
|
||||||
if (subs.size() == 0) {
|
|
||||||
/* None left. Terminate this goal and let someone else deal
|
|
||||||
with it. */
|
|
||||||
printMsg(lvlError,
|
|
||||||
format("path `%1%' is required, but there is no substituter that can build it")
|
|
||||||
% storePath);
|
|
||||||
amDone(ecFailed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub = subs.front();
|
|
||||||
subs.pop_front();
|
|
||||||
|
|
||||||
state = &SubstitutionGoal::tryToRun;
|
state = &SubstitutionGoal::tryToRun;
|
||||||
worker.waitForBuildSlot(shared_from_this());
|
worker.waitForBuildSlot(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,38 +541,44 @@ bool LocalStore::hasSubstitutes(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LocalStore::querySubstitutablePathInfo(const Path & substituter,
|
||||||
|
const Path & path, SubstitutablePathInfo & info)
|
||||||
|
{
|
||||||
|
RunningSubstituter & run(runningSubstituters[substituter]);
|
||||||
|
startSubstituter(substituter, run);
|
||||||
|
|
||||||
|
*run.to << "info\n" << path << "\n" << std::flush;
|
||||||
|
|
||||||
|
string s;
|
||||||
|
|
||||||
|
int res;
|
||||||
|
getline(*run.from, s);
|
||||||
|
if (!string2Int(s, res)) abort();
|
||||||
|
|
||||||
|
if (!res) return false;
|
||||||
|
|
||||||
|
getline(*run.from, info.deriver);
|
||||||
|
int nrRefs;
|
||||||
|
getline(*run.from, s);
|
||||||
|
if (!string2Int(s, nrRefs)) abort();
|
||||||
|
while (nrRefs--) {
|
||||||
|
Path p; getline(*run.from, p);
|
||||||
|
info.references.insert(p);
|
||||||
|
}
|
||||||
|
getline(*run.from, s);
|
||||||
|
long long size;
|
||||||
|
if (!string2Int(s, size)) abort();
|
||||||
|
info.downloadSize = size;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LocalStore::querySubstitutablePathInfo(const Path & path,
|
bool LocalStore::querySubstitutablePathInfo(const Path & path,
|
||||||
SubstitutablePathInfo & info)
|
SubstitutablePathInfo & info)
|
||||||
{
|
{
|
||||||
foreach (Paths::iterator, i, substituters) {
|
foreach (Paths::iterator, i, substituters)
|
||||||
RunningSubstituter & run(runningSubstituters[*i]);
|
if (querySubstitutablePathInfo(*i, path, info)) return true;
|
||||||
startSubstituter(*i, run);
|
|
||||||
|
|
||||||
*run.to << "info\n" << path << "\n" << std::flush;
|
|
||||||
|
|
||||||
string s;
|
|
||||||
|
|
||||||
int res;
|
|
||||||
getline(*run.from, s);
|
|
||||||
if (!string2Int(s, res)) abort();
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
getline(*run.from, info.deriver);
|
|
||||||
int nrRefs;
|
|
||||||
getline(*run.from, s);
|
|
||||||
if (!string2Int(s, nrRefs)) abort();
|
|
||||||
while (nrRefs--) {
|
|
||||||
Path p; getline(*run.from, p);
|
|
||||||
info.references.insert(p);
|
|
||||||
}
|
|
||||||
getline(*run.from, s);
|
|
||||||
long long size;
|
|
||||||
if (!string2Int(s, size)) abort();
|
|
||||||
info.downloadSize = size;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,9 @@ public:
|
||||||
bool querySubstitutablePathInfo(const Path & path,
|
bool querySubstitutablePathInfo(const Path & path,
|
||||||
SubstitutablePathInfo & info);
|
SubstitutablePathInfo & info);
|
||||||
|
|
||||||
|
bool querySubstitutablePathInfo(const Path & substituter,
|
||||||
|
const Path & path, SubstitutablePathInfo & info);
|
||||||
|
|
||||||
Path addToStore(const Path & srcPath, bool fixed = false,
|
Path addToStore(const Path & srcPath, bool fixed = false,
|
||||||
bool recursive = false, string hashAlgo = "",
|
bool recursive = false, string hashAlgo = "",
|
||||||
PathFilter & filter = defaultPathFilter);
|
PathFilter & filter = defaultPathFilter);
|
||||||
|
|
Loading…
Reference in a new issue