libstore: break up QueryMissingContext::doPath
std::visit makes coroutines nearly impossible to use correctly.
Change-Id: I085c08b595a5d4a43208eb97f023aa00b48bff45
This commit is contained in:
parent
74d820e5e8
commit
a911b44a31
|
@ -182,105 +182,112 @@ struct QueryMissingContext
|
||||||
if (!state->done.insert(req.to_string(store)).second) return;
|
if (!state->done.insert(req.to_string(store)).second) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::visit(overloaded {
|
std::visit(
|
||||||
[&](const DerivedPath::Built & bfd) {
|
overloaded{
|
||||||
auto drvPathP = std::get_if<DerivedPath::Opaque>(&*bfd.drvPath);
|
[&](const DerivedPath::Built & bfd) { doPathBuilt(bfd); },
|
||||||
if (!drvPathP) {
|
[&](const DerivedPath::Opaque & bo) { doPathOpaque(bo); },
|
||||||
// TODO make work in this case.
|
},
|
||||||
warn("Ignoring dynamic derivation %s while querying missing paths; not yet implemented", bfd.drvPath->to_string(store));
|
req.raw()
|
||||||
return;
|
);
|
||||||
}
|
}
|
||||||
auto & drvPath = drvPathP->path;
|
|
||||||
|
|
||||||
if (!store.isValidPath(drvPath)) {
|
void doPathBuilt(const DerivedPath::Built & bfd)
|
||||||
// FIXME: we could try to substitute the derivation.
|
{
|
||||||
auto state(state_.lock());
|
auto drvPathP = std::get_if<DerivedPath::Opaque>(&*bfd.drvPath);
|
||||||
state->unknown.insert(drvPath);
|
if (!drvPathP) {
|
||||||
return;
|
// TODO make work in this case.
|
||||||
}
|
warn("Ignoring dynamic derivation %s while querying missing paths; not yet implemented", bfd.drvPath->to_string(store));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto & drvPath = drvPathP->path;
|
||||||
|
|
||||||
StorePathSet invalid;
|
if (!store.isValidPath(drvPath)) {
|
||||||
/* true for regular derivations, and CA derivations for which we
|
// FIXME: we could try to substitute the derivation.
|
||||||
have a trust mapping for all wanted outputs. */
|
auto state(state_.lock());
|
||||||
auto knownOutputPaths = true;
|
state->unknown.insert(drvPath);
|
||||||
for (auto & [outputName, pathOpt] : store.queryPartialDerivationOutputMap(drvPath)) {
|
return;
|
||||||
if (!pathOpt) {
|
}
|
||||||
|
|
||||||
|
StorePathSet invalid;
|
||||||
|
/* true for regular derivations, and CA derivations for which we
|
||||||
|
have a trust mapping for all wanted outputs. */
|
||||||
|
auto knownOutputPaths = true;
|
||||||
|
for (auto & [outputName, pathOpt] : store.queryPartialDerivationOutputMap(drvPath)) {
|
||||||
|
if (!pathOpt) {
|
||||||
|
knownOutputPaths = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bfd.outputs.contains(outputName) && !store.isValidPath(*pathOpt))
|
||||||
|
invalid.insert(*pathOpt);
|
||||||
|
}
|
||||||
|
if (knownOutputPaths && invalid.empty()) return;
|
||||||
|
|
||||||
|
auto drv = make_ref<Derivation>(store.derivationFromPath(drvPath));
|
||||||
|
ParsedDerivation parsedDrv(StorePath(drvPath), *drv);
|
||||||
|
|
||||||
|
if (!knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
|
||||||
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
|
|
||||||
|
// If there are unknown output paths, attempt to find if the
|
||||||
|
// paths are known to substituters through a realisation.
|
||||||
|
auto outputHashes = staticOutputHashes(store, *drv);
|
||||||
|
knownOutputPaths = true;
|
||||||
|
|
||||||
|
for (auto [outputName, hash] : outputHashes) {
|
||||||
|
if (!bfd.outputs.contains(outputName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (auto &sub : getDefaultSubstituters()) {
|
||||||
|
auto realisation = sub->queryRealisation({hash, outputName});
|
||||||
|
if (!realisation)
|
||||||
|
continue;
|
||||||
|
found = true;
|
||||||
|
if (!store.isValidPath(realisation->outPath))
|
||||||
|
invalid.insert(realisation->outPath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
// Some paths did not have a realisation, this must be built.
|
||||||
knownOutputPaths = false;
|
knownOutputPaths = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bfd.outputs.contains(outputName) && !store.isValidPath(*pathOpt))
|
|
||||||
invalid.insert(*pathOpt);
|
|
||||||
}
|
}
|
||||||
if (knownOutputPaths && invalid.empty()) return;
|
}
|
||||||
|
|
||||||
auto drv = make_ref<Derivation>(store.derivationFromPath(drvPath));
|
if (knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
|
||||||
ParsedDerivation parsedDrv(StorePath(drvPath), *drv);
|
auto drvState = make_ref<Sync<DrvState>>(DrvState(invalid.size()));
|
||||||
|
for (auto & output : invalid)
|
||||||
|
pool.enqueue([=, this] { checkOutput(drvPath, drv, output, drvState); });
|
||||||
|
} else
|
||||||
|
mustBuildDrv(drvPath, *drv);
|
||||||
|
}
|
||||||
|
|
||||||
if (!knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
|
void doPathOpaque(const DerivedPath::Opaque & bo)
|
||||||
experimentalFeatureSettings.require(Xp::CaDerivations);
|
{
|
||||||
|
if (store.isValidPath(bo.path)) return;
|
||||||
|
|
||||||
// If there are unknown output paths, attempt to find if the
|
SubstitutablePathInfos infos;
|
||||||
// paths are known to substituters through a realisation.
|
store.querySubstitutablePathInfos({{bo.path, std::nullopt}}, infos);
|
||||||
auto outputHashes = staticOutputHashes(store, *drv);
|
|
||||||
knownOutputPaths = true;
|
|
||||||
|
|
||||||
for (auto [outputName, hash] : outputHashes) {
|
if (infos.empty()) {
|
||||||
if (!bfd.outputs.contains(outputName))
|
auto state(state_.lock());
|
||||||
continue;
|
state->unknown.insert(bo.path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = false;
|
auto info = infos.find(bo.path);
|
||||||
for (auto &sub : getDefaultSubstituters()) {
|
assert(info != infos.end());
|
||||||
auto realisation = sub->queryRealisation({hash, outputName});
|
|
||||||
if (!realisation)
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
if (!store.isValidPath(realisation->outPath))
|
|
||||||
invalid.insert(realisation->outPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
// Some paths did not have a realisation, this must be built.
|
|
||||||
knownOutputPaths = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
|
{
|
||||||
auto drvState = make_ref<Sync<DrvState>>(DrvState(invalid.size()));
|
auto state(state_.lock());
|
||||||
for (auto & output : invalid)
|
state->willSubstitute.insert(bo.path);
|
||||||
pool.enqueue([=, this] { checkOutput(drvPath, drv, output, drvState); });
|
state->downloadSize += info->second.downloadSize;
|
||||||
} else
|
state->narSize += info->second.narSize;
|
||||||
mustBuildDrv(drvPath, *drv);
|
}
|
||||||
|
|
||||||
},
|
for (auto & ref : info->second.references)
|
||||||
[&](const DerivedPath::Opaque & bo) {
|
pool.enqueue([this, path{DerivedPath::Opaque { ref }}] { doPath(path); });
|
||||||
|
|
||||||
if (store.isValidPath(bo.path)) return;
|
|
||||||
|
|
||||||
SubstitutablePathInfos infos;
|
|
||||||
store.querySubstitutablePathInfos({{bo.path, std::nullopt}}, infos);
|
|
||||||
|
|
||||||
if (infos.empty()) {
|
|
||||||
auto state(state_.lock());
|
|
||||||
state->unknown.insert(bo.path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto info = infos.find(bo.path);
|
|
||||||
assert(info != infos.end());
|
|
||||||
|
|
||||||
{
|
|
||||||
auto state(state_.lock());
|
|
||||||
state->willSubstitute.insert(bo.path);
|
|
||||||
state->downloadSize += info->second.downloadSize;
|
|
||||||
state->narSize += info->second.narSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto & ref : info->second.references)
|
|
||||||
pool.enqueue([this, path{DerivedPath::Opaque { ref }}] { doPath(path); });
|
|
||||||
},
|
|
||||||
}, req.raw());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue