fn write_chunked_field(
field_key: &str,
value: &str,
generation: &str,
) -> Result<Vec<(String, PriorKeychainState)>, StoreError>Expand description
Write value to field_key as one or more chunk entries (each under
MAX_CHUNK_LEN) plus a :count entry, clearing any stale trailing
chunks left over from a previous, longer value at this key, and stamps
generation (same value across all three fields for one
write_split_tokens call — see new_generation’s doc comment) on this
field’s :gen entry. Rolls back everything this call touched if any
single write/delete fails partway through.
Write order matters here beyond just “rollback on failure” (reagent P1:
a prior version wrote chunks, then cleared stale trailing chunks, then
updated :count, then :gen, in that order — a process CRASH between
the chunk-write and the trailing-chunk-delete left :count still
pointing at the OLD larger count while the leading chunks already held
NEW content; on restart read_chunked_field would read exactly
old_count chunks — none technically missing, so no error — silently
reconstructing a spliced new-prefix/old-suffix value that’s neither the
old nor the new token, with :gen untouched so read_split_tokens’s
cross-field generation check never even saw a mismatch to catch). This
version deletes :gen FIRST, before touching any chunk content, and
writes the fresh generation value LAST, only once chunks + :count
are fully consistent — read_chunked_field already treats a missing
:gen on an otherwise-populated field as an error, so a crash ANYWHERE
in between now makes this field unambiguously detectable as torn,
rather than silently reconstructible.
On success, returns the PRE-call state of every entry touched (:gen,
chunks, :count), so a caller doing more work of its own afterward
(write_split_tokens covering a sibling field, or muxbus_save’s SQL
write) can roll all of it back together if that later step fails too.