24866b71c4
In many cases we are dealing with a collection of realisations, they are all outputs of the same derivation. In that case, we don't need "derivation hashes modulos" to be part of our map key, because the output names alone will be unique. Those hashes are still part of the realisation proper, so we aren't loosing any information, we're just "normalizing our schema" by narrowing the "primary key". Besides making our data model a bit "tighter" this allows us to avoid a double `for` loop in `DerivationGoal::waiteeDone`. The inner `for` loop was previously just to select the output we cared about without knowing its hash. Now we can just select the output by name directly. Note that neither protocol is changed as part of this: we are still transferring `DrvOutputs` over the wire for `BuildResult`s. I would only consider revising this once #6223 is merged, and we can mention protocol versions inside factored-out serialization logic. Until then it is better not change anything because it would come a the cost of code reuse.
126 lines
3.4 KiB
C++
126 lines
3.4 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include "realisation.hh"
|
|
#include "derived-path.hh"
|
|
|
|
#include <string>
|
|
#include <chrono>
|
|
#include <optional>
|
|
|
|
namespace nix {
|
|
|
|
struct BuildResult
|
|
{
|
|
/**
|
|
* @note This is directly used in the nix-store --serve protocol.
|
|
* That means we need to worry about compatability across versions.
|
|
* Therefore, don't remove status codes, and only add new status
|
|
* codes at the end of the list.
|
|
*/
|
|
enum Status {
|
|
Built = 0,
|
|
Substituted,
|
|
AlreadyValid,
|
|
PermanentFailure,
|
|
InputRejected,
|
|
OutputRejected,
|
|
/// possibly transient
|
|
TransientFailure,
|
|
/// no longer used
|
|
CachedFailure,
|
|
TimedOut,
|
|
MiscFailure,
|
|
DependencyFailed,
|
|
LogLimitExceeded,
|
|
NotDeterministic,
|
|
ResolvesToAlreadyValid,
|
|
NoSubstituters,
|
|
} status = MiscFailure;
|
|
|
|
/**
|
|
* Information about the error if the build failed.
|
|
*
|
|
* @todo This should be an entire ErrorInfo object, not just a
|
|
* string, for richer information.
|
|
*/
|
|
std::string errorMsg;
|
|
|
|
std::string toString() const {
|
|
auto strStatus = [&]() {
|
|
switch (status) {
|
|
case Built: return "Built";
|
|
case Substituted: return "Substituted";
|
|
case AlreadyValid: return "AlreadyValid";
|
|
case PermanentFailure: return "PermanentFailure";
|
|
case InputRejected: return "InputRejected";
|
|
case OutputRejected: return "OutputRejected";
|
|
case TransientFailure: return "TransientFailure";
|
|
case CachedFailure: return "CachedFailure";
|
|
case TimedOut: return "TimedOut";
|
|
case MiscFailure: return "MiscFailure";
|
|
case DependencyFailed: return "DependencyFailed";
|
|
case LogLimitExceeded: return "LogLimitExceeded";
|
|
case NotDeterministic: return "NotDeterministic";
|
|
case ResolvesToAlreadyValid: return "ResolvesToAlreadyValid";
|
|
case NoSubstituters: return "NoSubstituters";
|
|
default: return "Unknown";
|
|
};
|
|
}();
|
|
return strStatus + ((errorMsg == "") ? "" : " : " + errorMsg);
|
|
}
|
|
|
|
/**
|
|
* How many times this build was performed.
|
|
*/
|
|
unsigned int timesBuilt = 0;
|
|
|
|
/**
|
|
* If timesBuilt > 1, whether some builds did not produce the same
|
|
* result. (Note that 'isNonDeterministic = false' does not mean
|
|
* the build is deterministic, just that we don't have evidence of
|
|
* non-determinism.)
|
|
*/
|
|
bool isNonDeterministic = false;
|
|
|
|
/**
|
|
* For derivations, a mapping from the names of the wanted outputs
|
|
* to actual paths.
|
|
*/
|
|
SingleDrvOutputs builtOutputs;
|
|
|
|
/**
|
|
* The start/stop times of the build (or one of the rounds, if it
|
|
* was repeated).
|
|
*/
|
|
time_t startTime = 0, stopTime = 0;
|
|
|
|
/**
|
|
* User and system CPU time the build took.
|
|
*/
|
|
std::optional<std::chrono::microseconds> cpuUser, cpuSystem;
|
|
|
|
bool success()
|
|
{
|
|
return status == Built || status == Substituted || status == AlreadyValid || status == ResolvesToAlreadyValid;
|
|
}
|
|
|
|
void rethrow()
|
|
{
|
|
throw Error("%s", errorMsg);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A `BuildResult` together with its "primary key".
|
|
*/
|
|
struct KeyedBuildResult : BuildResult
|
|
{
|
|
/**
|
|
* The derivation we built or the store path we substituted.
|
|
*/
|
|
DerivedPath path;
|
|
};
|
|
|
|
}
|