Skip to content

Commit

Permalink
Make KeyedBuildResult, put back BuildResult the way it was before
Browse files Browse the repository at this point in the history
In NixOS#6311 (comment), I
realized since derivation goals' wanted outputs can "grow" due to
overlapping dependencies (See `DerivationGoal::addWantedOutputs`), the
`DerivedPath` in the `BuildResult` in `DerivationGoal` cannot be
trusted; it is merely the *first* `DerivedPath` for which this goal was
originally created.

To remedy this, I made `BuildResult` be like it was before, and instead
made `KeyedBuildResult` be a subclass wit the path. Only
`buildPathsWithResults` returns `KeyedBuildResult`s, everything else just
becomes like it was before, where the "key" is unambiguous from context.

I think separating the "primary key" field(s) from the other fields is
good practical in general anyways. (I would like to do the same thing
for `ValidPathInfo`.) Among other things, it allows constructions like
`std::map<Key, ThingWithKey>` where doesn't contain duplicate keys and
just precludes the possibility of those duplicate keys being out of
sync.

We might leverage the above to someday overload `buildPathsWithResults`
to take a *set* of return a *map* per the above.
  • Loading branch information
Ericson2314 committed Mar 25, 2022
1 parent d9cfd85 commit 5274be3
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 32 deletions.
10 changes: 7 additions & 3 deletions src/libstore/build-result.hh
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ struct BuildResult
non-determinism.) */
bool isNonDeterministic = false;

/* The derivation we built or the store path we substituted. */
DerivedPath path;

/* For derivations, a mapping from the names of the wanted outputs
to actual paths. */
DrvOutputs builtOutputs;
Expand All @@ -86,4 +83,11 @@ struct BuildResult
}
};

/* A build result together with it's "primary key" */
struct KeyedBuildResult : BuildResult
{
/* The derivation we built or the store path we substituted. */
DerivedPath path;
};

}
2 changes: 0 additions & 2 deletions src/libstore/build/derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,6 @@ void DerivationGoal::inputsRealised()
build hook. */
state = &DerivationGoal::tryToBuild;
worker.wakeUp(shared_from_this());

buildResult = BuildResult { .path = buildResult.path };
}

void DerivationGoal::started()
Expand Down
23 changes: 13 additions & 10 deletions src/libstore/build/entry-points.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,35 @@ void Store::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMod
}
}

std::vector<BuildResult> Store::buildPathsWithResults(
std::vector<KeyedBuildResult> Store::buildPathsWithResults(
const std::vector<DerivedPath> & reqs,
BuildMode buildMode,
std::shared_ptr<Store> evalStore)
{
Worker worker(*this, evalStore ? *evalStore : *this);

Goals goals;
std::vector<std::pair<GoalPtr, const DerivedPath &>> reqs2;

for (const auto & br : reqs) {
std::visit(overloaded {
[&](const DerivedPath::Built & bfd) {
goals.insert(worker.makeDerivationGoal(bfd.drvPath, bfd.outputs, buildMode));
auto g = std::visit(overloaded {
[&](const DerivedPath::Built & bfd) -> GoalPtr {
return worker.makeDerivationGoal(bfd.drvPath, bfd.outputs, buildMode);
},
[&](const DerivedPath::Opaque & bo) {
goals.insert(worker.makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair));
[&](const DerivedPath::Opaque & bo) -> GoalPtr {
return worker.makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair);
},
}, br.raw());
goals.insert(g);
reqs2.push_back({g, br});
}

worker.run(goals);

std::vector<BuildResult> results;
std::vector<KeyedBuildResult> results;

for (auto & i : goals)
results.push_back(i->buildResult);
for (auto & [gp, req] : reqs2)
results.push_back(KeyedBuildResult { gp->buildResult, req });

return results;
}
Expand All @@ -89,7 +93,6 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
return BuildResult {
.status = BuildResult::MiscFailure,
.errorMsg = e.msg(),
.path = DerivedPath::Built { .drvPath = drvPath },
};
};
}
Expand Down
1 change: 0 additions & 1 deletion src/libstore/build/goal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ struct Goal : public std::enable_shared_from_this<Goal>

Goal(Worker & worker, DerivedPath path)
: worker(worker)
, buildResult { .path = std::move(path) }
{
nrFailed = nrNoSubstituters = nrIncompleteClosure = 0;
exitCode = ecBusy;
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/build/local-derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
result.rethrow();
}

std::vector<BuildResult> buildPathsWithResults(
std::vector<KeyedBuildResult> buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode = bmNormal,
std::shared_ptr<Store> evalStore = nullptr) override
Expand Down
4 changes: 2 additions & 2 deletions src/libstore/legacy-ssh-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor

conn->to.flush();

BuildResult status { .path = DerivedPath::Built { .drvPath = drvPath } };
BuildResult status;
status.status = (BuildResult::Status) readInt(conn->from);
conn->from >> status.errorMsg;

Expand Down Expand Up @@ -317,7 +317,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor

conn->to.flush();

BuildResult result { .path = DerivedPath::Opaque { StorePath::dummy } };
BuildResult result;
result.status = (BuildResult::Status) readInt(conn->from);

if (!result.success()) {
Expand Down
41 changes: 30 additions & 11 deletions src/libstore/remote-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,26 @@ void write(const Store & store, Sink & out, const DrvOutput & drvOutput)
}


BuildResult read(const Store & store, Source & from, Phantom<BuildResult> _)
KeyedBuildResult read(const Store & store, Source & from, Phantom<KeyedBuildResult> _)
{
auto path = worker_proto::read(store, from, Phantom<DerivedPath> {});
BuildResult res { .path = path };
auto br = worker_proto::read(store, from, Phantom<BuildResult> {});
return KeyedBuildResult {
std::move(br),
.path = std::move(path),
};
}

void write(const Store & store, Sink & to, const KeyedBuildResult & res)
{
worker_proto::write(store, to, res.path);
worker_proto::write(store, to, static_cast<const BuildResult &>(res));
}


BuildResult read(const Store & store, Source & from, Phantom<BuildResult> _)
{
BuildResult res;
res.status = (BuildResult::Status) readInt(from);
from
>> res.errorMsg
Expand All @@ -108,7 +124,6 @@ BuildResult read(const Store & store, Source & from, Phantom<BuildResult> _)

void write(const Store & store, Sink & to, const BuildResult & res)
{
worker_proto::write(store, to, res.path);
to
<< res.status
<< res.errorMsg
Expand Down Expand Up @@ -810,7 +825,7 @@ void RemoteStore::buildPaths(const std::vector<DerivedPath> & drvPaths, BuildMod
readInt(conn->from);
}

std::vector<BuildResult> RemoteStore::buildPathsWithResults(
std::vector<KeyedBuildResult> RemoteStore::buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode,
std::shared_ptr<Store> evalStore)
Expand All @@ -825,7 +840,7 @@ std::vector<BuildResult> RemoteStore::buildPathsWithResults(
writeDerivedPaths(*this, conn, paths);
conn->to << buildMode;
conn.processStderr();
return worker_proto::read(*this, conn->from, Phantom<std::vector<BuildResult>> {});
return worker_proto::read(*this, conn->from, Phantom<std::vector<KeyedBuildResult>> {});
} else {
// Avoid deadlock.
conn_.reset();
Expand All @@ -834,20 +849,24 @@ std::vector<BuildResult> RemoteStore::buildPathsWithResults(
// fails, but meh.
buildPaths(paths, buildMode, evalStore);

std::vector<BuildResult> results;
std::vector<KeyedBuildResult> results;

for (auto & path : paths) {
std::visit(
overloaded {
[&](const DerivedPath::Opaque & bo) {
results.push_back(BuildResult {
.status = BuildResult::Substituted,
results.push_back(KeyedBuildResult {
{
.status = BuildResult::Substituted,
},
.path = bo,
});
},
[&](const DerivedPath::Built & bfd) {
BuildResult res {
.status = BuildResult::Built,
KeyedBuildResult res {
{
.status = BuildResult::Built
},
.path = bfd,
};

Expand Down Expand Up @@ -904,7 +923,7 @@ BuildResult RemoteStore::buildDerivation(const StorePath & drvPath, const BasicD
writeDerivation(conn->to, *this, drv);
conn->to << buildMode;
conn.processStderr();
BuildResult res { .path = DerivedPath::Built { .drvPath = drvPath } };
BuildResult res;
res.status = (BuildResult::Status) readInt(conn->from);
conn->from >> res.errorMsg;
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 29) {
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/remote-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public:

void buildPaths(const std::vector<DerivedPath> & paths, BuildMode buildMode, std::shared_ptr<Store> evalStore) override;

std::vector<BuildResult> buildPathsWithResults(
std::vector<KeyedBuildResult> buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode,
std::shared_ptr<Store> evalStore) override;
Expand Down
3 changes: 2 additions & 1 deletion src/libstore/store-api.hh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const uint32_t exportMagic = 0x4558494e;
enum BuildMode { bmNormal, bmRepair, bmCheck };

struct BuildResult;
struct KeyedBuildResult;


struct StoreConfig : public Config
Expand Down Expand Up @@ -439,7 +440,7 @@ public:
a build/substitution error, this function won't throw an
exception, but return a `BuildResult` containing an error
message. */
virtual std::vector<BuildResult> buildPathsWithResults(
virtual std::vector<KeyedBuildResult> buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode = bmNormal,
std::shared_ptr<Store> evalStore = nullptr);
Expand Down
1 change: 1 addition & 0 deletions src/libstore/worker-protocol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ MAKE_WORKER_PROTO(, DerivedPath);
MAKE_WORKER_PROTO(, Realisation);
MAKE_WORKER_PROTO(, DrvOutput);
MAKE_WORKER_PROTO(, BuildResult);
MAKE_WORKER_PROTO(, KeyedBuildResult);

MAKE_WORKER_PROTO(template<typename T>, std::vector<T>);
MAKE_WORKER_PROTO(template<typename T>, std::set<T>);
Expand Down

0 comments on commit 5274be3

Please sign in to comment.