Skip to content

Commit 20db099

Browse files
committed
Factor out serialization for BuildResult
Worker Protocol: Note that the worker protocol already had a serialization for `BuildResult`; this was added in a4604f1. It didn't have any versioning support because at that time reusable seralizers were not away for the protocol version. It could thus only be used for new messages also introduced in that commit. Now that we do support versioning in reusable serializers, we can expand it to support all known versions and use it in many more places. The exist test data becomes the version 1.29 tests: note that those files' contents are unchanged. 1.28 and 1.27 tests are added to cover the older code-paths. The keyered build result test only has 1.29 because the keying was also added in a4604f1; the older serializations are always used unkeyed. Serve Protocol: Conversely, no attempt was made to factor out such a serializer for the serve protocol, so our work there in this commit for that protocol proceeds from scratch.
1 parent 6c1c5ff commit 20db099

16 files changed

+268
-76
lines changed

src/libstore/daemon.cc

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -647,16 +647,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
647647

648648
auto res = store->buildDerivation(drvPath, drv, buildMode);
649649
logger->stopWork();
650-
to << res.status << res.errorMsg;
651-
if (GET_PROTOCOL_MINOR(clientVersion) >= 29) {
652-
to << res.timesBuilt << res.isNonDeterministic << res.startTime << res.stopTime;
653-
}
654-
if (GET_PROTOCOL_MINOR(clientVersion) >= 28) {
655-
DrvOutputs builtOutputs;
656-
for (auto & [output, realisation] : res.builtOutputs)
657-
builtOutputs.insert_or_assign(realisation.id, realisation);
658-
WorkerProto::write(*store, wconn, builtOutputs);
659-
}
650+
WorkerProto::write(*store, wconn, res);
660651
break;
661652
}
662653

src/libstore/legacy-ssh-store.cc

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -319,20 +319,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
319319

320320
conn->to.flush();
321321

322-
BuildResult status;
323-
status.status = (BuildResult::Status) readInt(conn->from);
324-
conn->from >> status.errorMsg;
325-
326-
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 3)
327-
conn->from >> status.timesBuilt >> status.isNonDeterministic >> status.startTime >> status.stopTime;
328-
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 6) {
329-
auto builtOutputs = ServeProto::Serialise<DrvOutputs>::read(*this, *conn);
330-
for (auto && [output, realisation] : builtOutputs)
331-
status.builtOutputs.insert_or_assign(
332-
std::move(output.outputName),
333-
std::move(realisation));
334-
}
335-
return status;
322+
return ServeProto::Serialise<BuildResult>::read(*this, *conn);
336323
}
337324

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

src/libstore/remote-store.cc

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -815,20 +815,7 @@ BuildResult RemoteStore::buildDerivation(const StorePath & drvPath, const BasicD
815815
writeDerivation(conn->to, *this, drv);
816816
conn->to << buildMode;
817817
conn.processStderr();
818-
BuildResult res;
819-
res.status = (BuildResult::Status) readInt(conn->from);
820-
conn->from >> res.errorMsg;
821-
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 29) {
822-
conn->from >> res.timesBuilt >> res.isNonDeterministic >> res.startTime >> res.stopTime;
823-
}
824-
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 28) {
825-
auto builtOutputs = WorkerProto::Serialise<DrvOutputs>::read(*this, *conn);
826-
for (auto && [output, realisation] : builtOutputs)
827-
res.builtOutputs.insert_or_assign(
828-
std::move(output.outputName),
829-
std::move(realisation));
830-
}
831-
return res;
818+
return WorkerProto::Serialise<BuildResult>::read(*this, *conn);
832819
}
833820

834821

src/libstore/serve-protocol.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "util.hh"
33
#include "path-with-outputs.hh"
44
#include "store-api.hh"
5+
#include "build-result.hh"
56
#include "serve-protocol.hh"
67
#include "serve-protocol-impl.hh"
78
#include "archive.hh"
@@ -12,4 +13,46 @@ namespace nix {
1213

1314
/* protocol-specific definitions */
1415

16+
BuildResult ServeProto::Serialise<BuildResult>::read(const Store & store, ServeProto::ReadConn conn)
17+
{
18+
BuildResult status;
19+
status.status = (BuildResult::Status) readInt(conn.from);
20+
conn.from >> status.errorMsg;
21+
22+
if (GET_PROTOCOL_MINOR(conn.version) >= 3)
23+
conn.from
24+
>> status.timesBuilt
25+
>> status.isNonDeterministic
26+
>> status.startTime
27+
>> status.stopTime;
28+
if (GET_PROTOCOL_MINOR(conn.version) >= 6) {
29+
auto builtOutputs = ServeProto::Serialise<DrvOutputs>::read(store, conn);
30+
for (auto && [output, realisation] : builtOutputs)
31+
status.builtOutputs.insert_or_assign(
32+
std::move(output.outputName),
33+
std::move(realisation));
34+
}
35+
return status;
36+
}
37+
38+
void ServeProto::Serialise<BuildResult>::write(const Store & store, ServeProto::WriteConn conn, const BuildResult & status)
39+
{
40+
conn.to
41+
<< status.status
42+
<< status.errorMsg;
43+
44+
if (GET_PROTOCOL_MINOR(conn.version) >= 3)
45+
conn.to
46+
<< status.timesBuilt
47+
<< status.isNonDeterministic
48+
<< status.startTime
49+
<< status.stopTime;
50+
if (GET_PROTOCOL_MINOR(conn.version) >= 6) {
51+
DrvOutputs builtOutputs;
52+
for (auto & [output, realisation] : status.builtOutputs)
53+
builtOutputs.insert_or_assign(realisation.id, realisation);
54+
ServeProto::write(store, conn, builtOutputs);
55+
}
56+
}
57+
1558
}

src/libstore/serve-protocol.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ namespace nix {
1616
class Store;
1717
struct Source;
1818

19+
// items being serialised
20+
struct BuildResult;
21+
1922

2023
/**
2124
* The "serve protocol", used by ssh:// stores.
@@ -136,6 +139,9 @@ inline std::ostream & operator << (std::ostream & s, ServeProto::Command op)
136139
static void write(const Store & store, ServeProto::WriteConn conn, const T & t); \
137140
};
138141

142+
template<>
143+
DECLARE_SERVE_SERIALISER(BuildResult);
144+
139145
template<typename T>
140146
DECLARE_SERVE_SERIALISER(std::vector<T>);
141147
template<typename T>

src/libstore/tests/serve-protocol.cc

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct ServeProtoTest : VersionedProtoTest<ServeProto, serveProtoDir>
1919
* For serializers that don't care about the minimum version, we
2020
* used the oldest one: 1.0.
2121
*/
22-
ServeProto::Version defaultVersion = 1 << 8 | 0;
22+
ServeProto::Version defaultVersion = 2 << 8 | 0;
2323
};
2424

2525
VERSIONED_CHARACTERIZATION_TEST(
@@ -114,6 +114,117 @@ VERSIONED_CHARACTERIZATION_TEST(
114114
},
115115
}))
116116

117+
VERSIONED_CHARACTERIZATION_TEST(
118+
ServeProtoTest,
119+
buildResult_2_2,
120+
"build-result-2.2",
121+
2 << 8 | 2,
122+
({
123+
using namespace std::literals::chrono_literals;
124+
std::tuple<BuildResult, BuildResult, BuildResult> t {
125+
BuildResult {
126+
.status = BuildResult::OutputRejected,
127+
.errorMsg = "no idea why",
128+
},
129+
BuildResult {
130+
.status = BuildResult::NotDeterministic,
131+
.errorMsg = "no idea why",
132+
},
133+
BuildResult {
134+
.status = BuildResult::Built,
135+
},
136+
};
137+
t;
138+
}))
139+
140+
VERSIONED_CHARACTERIZATION_TEST(
141+
ServeProtoTest,
142+
buildResult_2_3,
143+
"build-result-2.3",
144+
2 << 8 | 3,
145+
({
146+
using namespace std::literals::chrono_literals;
147+
std::tuple<BuildResult, BuildResult, BuildResult> t {
148+
BuildResult {
149+
.status = BuildResult::OutputRejected,
150+
.errorMsg = "no idea why",
151+
},
152+
BuildResult {
153+
.status = BuildResult::NotDeterministic,
154+
.errorMsg = "no idea why",
155+
.timesBuilt = 3,
156+
.isNonDeterministic = true,
157+
.startTime = 30,
158+
.stopTime = 50,
159+
},
160+
BuildResult {
161+
.status = BuildResult::Built,
162+
.startTime = 30,
163+
.stopTime = 50,
164+
},
165+
};
166+
t;
167+
}))
168+
169+
VERSIONED_CHARACTERIZATION_TEST(
170+
ServeProtoTest,
171+
buildResult_2_6,
172+
"build-result-2.6",
173+
2 << 8 | 6,
174+
({
175+
using namespace std::literals::chrono_literals;
176+
std::tuple<BuildResult, BuildResult, BuildResult> t {
177+
BuildResult {
178+
.status = BuildResult::OutputRejected,
179+
.errorMsg = "no idea why",
180+
},
181+
BuildResult {
182+
.status = BuildResult::NotDeterministic,
183+
.errorMsg = "no idea why",
184+
.timesBuilt = 3,
185+
.isNonDeterministic = true,
186+
.startTime = 30,
187+
.stopTime = 50,
188+
},
189+
BuildResult {
190+
.status = BuildResult::Built,
191+
.timesBuilt = 1,
192+
.builtOutputs = {
193+
{
194+
"foo",
195+
{
196+
.id = DrvOutput {
197+
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
198+
.outputName = "foo",
199+
},
200+
.outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
201+
},
202+
},
203+
{
204+
"bar",
205+
{
206+
.id = DrvOutput {
207+
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
208+
.outputName = "bar",
209+
},
210+
.outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar" },
211+
},
212+
},
213+
},
214+
.startTime = 30,
215+
.stopTime = 50,
216+
#if 0
217+
// These fields are not yet serialized.
218+
// FIXME Include in next version of protocol or document
219+
// why they are skipped.
220+
.cpuUser = std::chrono::milliseconds(500s),
221+
.cpuSystem = std::chrono::milliseconds(604s),
222+
#endif
223+
},
224+
};
225+
t;
226+
}))
227+
117228
VERSIONED_CHARACTERIZATION_TEST(
118229
ServeProtoTest,
119230
vector,

src/libstore/tests/worker-protocol.cc

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,77 @@ VERSIONED_CHARACTERIZATION_TEST(
135135

136136
VERSIONED_CHARACTERIZATION_TEST(
137137
WorkerProtoTest,
138-
buildResult,
139-
"build-result",
140-
defaultVersion,
138+
buildResult_1_27,
139+
"build-result-1.27",
140+
1 << 8 | 27,
141+
({
142+
using namespace std::literals::chrono_literals;
143+
std::tuple<BuildResult, BuildResult, BuildResult> t {
144+
BuildResult {
145+
.status = BuildResult::OutputRejected,
146+
.errorMsg = "no idea why",
147+
},
148+
BuildResult {
149+
.status = BuildResult::NotDeterministic,
150+
.errorMsg = "no idea why",
151+
},
152+
BuildResult {
153+
.status = BuildResult::Built,
154+
},
155+
};
156+
t;
157+
}))
158+
159+
VERSIONED_CHARACTERIZATION_TEST(
160+
WorkerProtoTest,
161+
buildResult_1_28,
162+
"build-result-1.28",
163+
1 << 8 | 28,
164+
({
165+
using namespace std::literals::chrono_literals;
166+
std::tuple<BuildResult, BuildResult, BuildResult> t {
167+
BuildResult {
168+
.status = BuildResult::OutputRejected,
169+
.errorMsg = "no idea why",
170+
},
171+
BuildResult {
172+
.status = BuildResult::NotDeterministic,
173+
.errorMsg = "no idea why",
174+
},
175+
BuildResult {
176+
.status = BuildResult::Built,
177+
.builtOutputs = {
178+
{
179+
"foo",
180+
{
181+
.id = DrvOutput {
182+
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
183+
.outputName = "foo",
184+
},
185+
.outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
186+
},
187+
},
188+
{
189+
"bar",
190+
{
191+
.id = DrvOutput {
192+
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
193+
.outputName = "bar",
194+
},
195+
.outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar" },
196+
},
197+
},
198+
},
199+
},
200+
};
201+
t;
202+
}))
203+
204+
VERSIONED_CHARACTERIZATION_TEST(
205+
WorkerProtoTest,
206+
buildResult_1_29,
207+
"build-result-1.29",
208+
1 << 8 | 29,
141209
({
142210
using namespace std::literals::chrono_literals;
143211
std::tuple<BuildResult, BuildResult, BuildResult> t {
@@ -194,9 +262,9 @@ VERSIONED_CHARACTERIZATION_TEST(
194262

195263
VERSIONED_CHARACTERIZATION_TEST(
196264
WorkerProtoTest,
197-
keyedBuildResult,
198-
"keyed-build-result",
199-
defaultVersion,
265+
keyedBuildResult_1_29,
266+
"keyed-build-result-1.29",
267+
1 << 8 | 29,
200268
({
201269
using namespace std::literals::chrono_literals;
202270
std::tuple<KeyedBuildResult, KeyedBuildResult/*, KeyedBuildResult*/> t {

0 commit comments

Comments
 (0)