Yield recovery container encoding without changing durable cuts
This commit is contained in:
+25
-1
@@ -978,10 +978,34 @@ changes still commit in one transaction. No Root is skipped. Reopening validates
|
||||
headers/sequence, hashes exact Blob bytes, decodes strict UTF-8, checks the decoded
|
||||
header and then applies later deltas. Future checkpoint versions reject reads
|
||||
and writes; malformed/tampered data is never treated as an empty document. Legacy
|
||||
recovery, JSON parse, recovery-image encoding, same-cut retry comparison and
|
||||
recovery, JSON parse, recovery-image capture, same-cut retry comparison and
|
||||
individual native operations still have synchronous work; this is not a strict
|
||||
6ms bound for all storage paths or a disk-space reduction guarantee.
|
||||
|
||||
Before Blob serialization, ProjectEngine now awaits cooperative recovery-image
|
||||
encoding inside its existing ordered Root writer. Private `dataArray` / `dataRecord`
|
||||
constructors copy and freeze DTO container membership; they do not claim their
|
||||
children are immutable. Preparation captures each unknown subtree synchronously,
|
||||
including getters, custom `toJSON`, Dates and external shallow-frozen records.
|
||||
Previously validated immutable codec facts can be reused. Only then does a
|
||||
budgeted traversal assemble the owned containers, preserving key order, omitted
|
||||
values, sparse-array normalization, depth checks and exact UTF-8 byte facts.
|
||||
The default uses `scheduler.yield()` when available (with its receiver), otherwise
|
||||
a timer, sharing the 6ms soft budget / 16384-work ceiling. One shared budget spans
|
||||
nested containers. Public synchronous encoding and recovery/storage formats stay
|
||||
unchanged; async images receive the same codec ownership seal without a second
|
||||
full encoding pass.
|
||||
|
||||
A yield does not publish or skip a Root. Later edits may publish while encoding
|
||||
is suspended; the old image still contains its captured state, and the next cut
|
||||
is saved after it. Request dispatch retains the durable-prefix barrier. Encoding
|
||||
or scheduling failures retain the pending Root for retry and produce no partial
|
||||
storage commit. Initial DTO membership copying, synchronous preparation, unknown
|
||||
subtrees, first-time immutable normalization and individual scalar operations
|
||||
remain synchronous. This is partial time slicing, not a strict whole-Root latency
|
||||
bound. In particular, large history/import objects still need producer ownership
|
||||
review before their internal loops can safely be deferred.
|
||||
|
||||
A blocked schema upgrade retires its pending open. If the old connection closes
|
||||
later, that abandoned request aborts in `onupgradeneeded` rather than silently
|
||||
upgrading after rejection. A fresh adapter can retry once the blocking client has
|
||||
|
||||
Reference in New Issue
Block a user