Skip to content

Commit 7839bf1

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 ee75728 commit 7839bf1

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
@@ -635,16 +635,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
635635

636636
auto res = store->buildDerivation(drvPath, drv, buildMode);
637637
logger->stopWork();
638-
to << res.status << res.errorMsg;
639-
if (GET_PROTOCOL_MINOR(clientVersion) >= 29) {
640-
to << res.timesBuilt << res.isNonDeterministic << res.startTime << res.stopTime;
641-
}
642-
if (GET_PROTOCOL_MINOR(clientVersion) >= 28) {
643-
DrvOutputs builtOutputs;
644-
for (auto & [output, realisation] : res.builtOutputs)
645-
builtOutputs.insert_or_assign(realisation.id, realisation);
646-
WorkerProto::write(*store, wconn, builtOutputs);
647-
}
638+
WorkerProto::write(*store, wconn, res);
648639
break;
649640
}
650641

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
@@ -788,20 +788,7 @@ BuildResult RemoteStore::buildDerivation(const StorePath & drvPath, const BasicD
788788
writeDerivation(conn->to, *this, drv);
789789
conn->to << buildMode;
790790
conn.processStderr();
791-
BuildResult res;
792-
res.status = (BuildResult::Status) readInt(conn->from);
793-
conn->from >> res.errorMsg;
794-
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 29) {
795-
conn->from >> res.timesBuilt >> res.isNonDeterministic >> res.startTime >> res.stopTime;
796-
}
797-
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 28) {
798-
auto builtOutputs = WorkerProto::Serialise<DrvOutputs>::read(*this, *conn);
799-
for (auto && [output, realisation] : builtOutputs)
800-
res.builtOutputs.insert_or_assign(
801-
std::move(output.outputName),
802-
std::move(realisation));
803-
}
804-
return res;
791+
return WorkerProto::Serialise<BuildResult>::read(*this, *conn);
805792
}
806793

807794

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
@@ -167,9 +167,77 @@ VERSIONED_CHARACTERIZATION_TEST(
167167

168168
VERSIONED_CHARACTERIZATION_TEST(
169169
WorkerProtoTest,
170-
buildResult,
171-
"build-result",
172-
defaultVersion,
170+
buildResult_1_27,
171+
"build-result-1.27",
172+
1 << 8 | 27,
173+
({
174+
using namespace std::literals::chrono_literals;
175+
std::tuple<BuildResult, BuildResult, BuildResult> t {
176+
BuildResult {
177+
.status = BuildResult::OutputRejected,
178+
.errorMsg = "no idea why",
179+
},
180+
BuildResult {
181+
.status = BuildResult::NotDeterministic,
182+
.errorMsg = "no idea why",
183+
},
184+
BuildResult {
185+
.status = BuildResult::Built,
186+
},
187+
};
188+
t;
189+
}))
190+
191+
VERSIONED_CHARACTERIZATION_TEST(
192+
WorkerProtoTest,
193+
buildResult_1_28,
194+
"build-result-1.28",
195+
1 << 8 | 28,
196+
({
197+
using namespace std::literals::chrono_literals;
198+
std::tuple<BuildResult, BuildResult, BuildResult> t {
199+
BuildResult {
200+
.status = BuildResult::OutputRejected,
201+
.errorMsg = "no idea why",
202+
},
203+
BuildResult {
204+
.status = BuildResult::NotDeterministic,
205+
.errorMsg = "no idea why",
206+
},
207+
BuildResult {
208+
.status = BuildResult::Built,
209+
.builtOutputs = {
210+
{
211+
"foo",
212+
{
213+
.id = DrvOutput {
214+
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
215+
.outputName = "foo",
216+
},
217+
.outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
218+
},
219+
},
220+
{
221+
"bar",
222+
{
223+
.id = DrvOutput {
224+
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
225+
.outputName = "bar",
226+
},
227+
.outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar" },
228+
},
229+
},
230+
},
231+
},
232+
};
233+
t;
234+
}))
235+
236+
VERSIONED_CHARACTERIZATION_TEST(
237+
WorkerProtoTest,
238+
buildResult_1_29,
239+
"build-result-1.29",
240+
1 << 8 | 29,
173241
({
174242
using namespace std::literals::chrono_literals;
175243
std::tuple<BuildResult, BuildResult, BuildResult> t {
@@ -226,9 +294,9 @@ VERSIONED_CHARACTERIZATION_TEST(
226294

227295
VERSIONED_CHARACTERIZATION_TEST(
228296
WorkerProtoTest,
229-
keyedBuildResult,
230-
"keyed-build-result",
231-
defaultVersion,
297+
keyedBuildResult_1_29,
298+
"keyed-build-result-1.29",
299+
1 << 8 | 29,
232300
({
233301
using namespace std::literals::chrono_literals;
234302
std::tuple<KeyedBuildResult, KeyedBuildResult/*, KeyedBuildResult*/> t {

0 commit comments

Comments
 (0)