diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 22f1c64ae..33a53c148 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2187,14 +2187,34 @@ void SubstitutionGoal::init() 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, - 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); amDone(ecFailed); 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 paths referenced by this one. */ foreach (PathSet::iterator, i, info.references) @@ -2223,29 +2243,6 @@ void SubstitutionGoal::referencesValid() if (*i != storePath) /* ignore self-references */ 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; worker.waitForBuildSlot(shared_from_this()); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 141c7a852..ccf1a51bc 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -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, SubstitutablePathInfo & info) { - foreach (Paths::iterator, i, substituters) { - RunningSubstituter & run(runningSubstituters[*i]); - 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; - } - } - + foreach (Paths::iterator, i, substituters) + if (querySubstitutablePathInfo(*i, path, info)) return true; return false; } diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index f096bdd85..8266184f0 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -86,6 +86,9 @@ public: bool querySubstitutablePathInfo(const Path & path, SubstitutablePathInfo & info); + bool querySubstitutablePathInfo(const Path & substituter, + const Path & path, SubstitutablePathInfo & info); + Path addToStore(const Path & srcPath, bool fixed = false, bool recursive = false, string hashAlgo = "", PathFilter & filter = defaultPathFilter);