write method
Future<TrajectoryRequestSpill?>
write({
- required TrajectoryRequestDetail detail,
- String? rawWireDump,
- String redactWireDump()?,
Writes detail (plus the built rawWireDump, when the request
carried one) as one JSON blob and returns the spill outcome. Null on
any write failure — the caller falls back to the legacy inline
persistence (AC6 shape: the capture is never lost, never a crash).
redactWireDump is the host's active pipeline pass (E1: the dump is
redacted under the config active at capture time) and the dump rides
the same wireDumpMaxChars cap as the inline record did.
The FIRST write of a store instance also runs the boot-time TTL sweep (sweepOncePerBoot) — the store is built lazily at the first request of a session, so hosts need no extra wiring.
Implementation
Future<TrajectoryRequestSpill?> write({
required TrajectoryRequestDetail detail,
String? rawWireDump,
String Function(String)? redactWireDump,
}) async {
await sweepOncePerBoot();
final dump = rawWireDump == null
? null
: trajectoryBuildWireDump(rawWireDump, redact: redactWireDump);
final payload = jsonEncode({
'detail': detail.toJson(),
if (dump != null) 'wireDump': dump.toJson(),
});
final sid = _sessionId();
if (_counterSession != sid) {
_counterSession = sid;
_counter = 0;
}
if (_counter == 0) {
// Sequence numbers must survive a process restart on a resumed
// session: probe the dir once and continue past the highest
// existing file (a failed probe starts at 1 — worst case a legacy
// file of the same name is superseded, never merged).
_counter = await _maxExistingSequence(sid);
}
_counter++;
final file = '${trajectoryRequestBlobDir(sid)}/$_counter.json';
final written = await _env.writeBinaryFile(file, utf8.encode(payload));
if (written.isErr) return null;
await _maybeSweep(payload.length);
return TrajectoryRequestSpill(file: file, wireDumpHash: dump?.hash);
}