Skip to main content

Performance

App state sync: move-not-clone through the blocking thread handoff (#818) process_patch_list offloads snapshot and patch processing to runtime::blocking, whose closure requires 'static. Previously, the only way to satisfy that bound was to deep-clone the data before moving it in:
eliminated copyshapemeasured cost
snapshot.clone() per bootstrap~20k records × 1 KB (~21 MB)~8.4 ms, ~60k allocs
patch.clone() per resume patch~1k mutations × 2 KB (~2 MB)~305 µs, ~3k allocs
keys_map.clone() per patchkey-cache HashMapnow an Arc refcount bump
How it works. The snapshot is taken out of PatchList with Option::take, moved into the blocking closure, returned through the result tuple, and restored to pl.snapshot before the function returns. Patches are drained with mem::take, processed one by one the same way, and reassembled in order into pl.patches. The key cache is wrapped in Arc once so each per-patch closure handoff is a cheap refcount increment. The staleness guard runs on a borrow before the take, so its behavior is unchanged. On any error path ? propagates before the caller can observe the intermediate empty fields. The caller contract (get_missing_key_ids and has-more bookkeeping read pl.snapshot and pl.patches after the call) is protected by a regression test.

Breaking changes

None. process_patch_list keeps its existing signature and returns a PatchList carrying the same data as before.