Repository navigation
perf(acp): avoid repeated observer batch serialization - #9483
Conversation
Reuse cached event sizes when packing observer frames. Measure only the outer envelope for each candidate and build the payload once per completed batch. Co-authored-by: Codex <[email protected]> Signed-off-by: Sanket Kanjalkar <[email protected]>
🔐 Codex Security Review
Review SummaryOverall Risk: NONE
FindingsNo concrete security, correctness, or reliability findings were identified. Notes
Generated by Codex Security Review | |
joahg
left a comment
There was a problem hiding this comment.
🤖 No blocking findings. I checked the new packing math against the old one, and it is equivalent. The old code serialized the whole envelope after pushing event N, with the envelope metadata taken from that newest event. The new code measures empty_batch_envelope(&event) (that metadata plus the [] brackets), adds the cached post-fit event sizes, and adds one comma per preceding event. That is the same byte count. The first event is always taken, so a single oversized event still ships unwrapped. The overflow event goes back to the head of its channel's queue, pending_bytes only drops for picked events, and channel barriers and FIFO order are unchanged. The cached sizes cannot go stale, because queued events are only mutated inside fit_observer_event_to_budget before the size is recorded, and that function returns the exact serialized length on every path. The exact-limit test uses an independent wire oracle (escaping, UTF-8, optional metadata, commas) at limit -1, 0 and +1, so it covers the packing boundary. The ignored probe is manual only, with no CI timing gate, which fits the PR's claims. The test move looks mechanical; the CI checks are green.
Optional: the PR body says to keep it in draft pending native and relay latency checks and human verification, but it is currently marked ready.
I did not run the tests or the probe locally, and I did not re-diff every moved test line for exactness.
| // Add cached event sizes and one comma per preceding event; | ||
| // only the newest event's envelope metadata needs measuring. | ||
| if !picked.is_empty() | ||
| && serialized_len(&empty_batch_envelope(&event)) |
There was a problem hiding this comment.
🤖 Optional: serialized_len returns usize::MAX on a serialization error, and this sum now adds to it. The old code only compared against it. That can't realistically fail for a string-and-[] envelope, but saturating_add would keep the old fail-closed behavior at no cost.
There was a problem hiding this comment.
sure, i can make this saturing_add . does not hurt adding it
kazemek21
left a comment
There was a problem hiding this comment.
Kyle reviewed this PR and the Nexus review-tracker notes and approved with no comments.
Posted by Codex (gpt-6.1-sol) on behalf of kylez
…eaction-recipients * origin/main: (111 commits) perf(acp): avoid repeated observer batch serialization (#9483) docs(readme): point desktop readers at block/buzz-app and describe where each client lives (#9493) test(cli,db): freeze the assertion test clock and give pool release tests a test-lane acquire budget (#9442) test(desktop): unmount every TerminalSubstrate tree before the window closes (#9440) fix(mobile): drop the iOS share extension from the build until it's signed (#9489) chore(release): release Buzz Desktop version 0.5.30 (#9491) perf(mobile): parse each event's thread reference once (#9460) perf(mobile): load only the directory when search opens (#9466) perf(mobile): stop rebuilding Home's channel list when a route covers it (#9459) perf(mobile): ask typing subscriptions only for the typing window (#9454) perf(mobile): skip avatar URL parsing for non-HTTP URLs (#9448) perf(mobile): download the identity archive list only when it changed (#9445) perf(mobile): don't treat a Control Center pull as a resume (#9443) fix(mobile): keep a superseded roster read out of the offline snapshot (#9452) perf(mobile): read channel bot roles from the member list (#9451) perf(mobile): read Activity once per reconnect (#9455) fix(mobile): offer role controls for agents (#9475) perf(mobile): stop rebuilding the native nav bar on every scrolled frame (#9458) perf(mobile): keep verified-name batches open as people are added (#9450) perf(mobile): read only changed custom emoji sets on reconnect (#9446) ... Signed-off-by: Matthew Boston <[email protected]>
Replaces #9413 with the packing optimization refreshed against main on a branch in this repository.
Summary
Busy agent activity streams repeatedly build and serialize a growing JSON batch just to check whether the next event fits. Reuse cached event sizes, measure the newest outer envelope, and build the batch payload once per completed frame.
Preserve the wire format, greedy packing, per-channel order, channel barriers, byte budget, and one-frame-per-second relay cadence. Exact-limit coverage checks escaping, UTF-8, optional metadata, and array separators. Move the queue tests into a separate module to satisfy the file-size rule; their test names stay unchanged.
Related issue
Related to #7987. This builds on the merged fitting/locking work in #9381 and retention limits in #9436. Closest earlier batching work: #4917. No duplicate packing fix found among open PRs.
Testing
The ignored probe fills the production queue before timing, drains every event, and checks complete FIFO delivery, frame byte limits, and empty byte accounting.
Five alternating fresh release processes per arm and workload compared baseline
59ae028a3with candidate237b928b9on macOS arm64, Rust 1.98.1. Both arms usedopt-level=3, thin LTO and four codegen units, with incremental compilation and compiler-cache wrappers off. Each executable was rebuilt separately and its probe identity verified. Medians:The one-event control measured 2.04 → 2.21 microseconds. The timed region covers packing only; ingestion, validation, encryption, publish pacing, relay delivery, and rendering are excluded. These local results do not establish an overall app latency improvement. No timing threshold was added to CI.
Native and deployed-relay latency, independent review, and human verification remain pending. Keep this PR in draft.
Generated with AI assistance