mirror of
https://github.com/block/buzz.git
synced 2026-11-13 21:01:53 +00:00
## Summary The Agent Client Protocol (ACP) observer records agent activity for the owner's viewer. Sizing currently allocates JSON strings and rescans whole frames for each trimmed field. Count JSON bytes directly, reuse fitted sizes, and count changed fields when cheaper. Skip raw-message copies for disabled observers and copy replay payloads outside the mutex. Keep sequence numbers, timestamps, replay insertion, and publication under one lock to preserve replay/live ordering. This adds one `Arc` allocation per replay entry, and snapshots pin entries until copying completes. Replay retains the existing 1,000-event limit. ### Related issue Related to #7987. This PR targets `main` independently of #9366, which owns the byte-budget fix. The changes overlap in observer plumbing, so the second PR to land will need a rebase. ### Testing The new ignored probe exercises the production publish queue. Timing includes template clones and queue ingestion, before encryption. Five alternating fresh release processes per arm/case compared `75d38b6c2` with this commit on a busy host. Every pair retained identical queue bytes and event counts. ```sh cargo test --release -p buzz-acp --lib observer::perf_tests::publish_queue_probe -- --exact --ignored --nocapture ``` Set `BUZZ_OBSERVER_PROBE_EVENTS`, `BUZZ_OBSERVER_PROBE_BYTES`, and `BUZZ_OBSERVER_PROBE_FIELDS` for each row. Medians: | Events / string bytes per event / fields | Before | After | | --- | ---: | ---: | | 200 / 1 MiB / 64 | 5605 ms | 228 ms | | 1,000 / 1 MiB / 1 | 714 ms | 352 ms | | 10,000 / 1 KiB / 1 | 13.01 ms | 6.90 ms | A separate 20-trial integration run used the same production Chromium app build (`block/buzz-app@128cd4c2`) and four real ACP subprocesses. Three peers emitted 225 synthetic messages over five seconds, each with 1 MiB across 64 strings. A fourth emitted 50 markers, 100 ms apart. Each arm/mode used five fresh processes and browser contexts, with alternating arm order. The real observer, publisher, encryption/signing, browser broker, and Activity UI ran through a modeled relay transport. Marker timing used one controller clock, from release through transcript DOM commit plus two animation frames. Observer timestamps were not the timing origin. Observation-enabled medians: | Metric | Before | After | | --- | ---: | ---: | | Rust CPU time | 4.49 s | 0.45 s | | Marker-to-render p95 | 4471 ms | 1018 ms | | Sampled peak RSS | 342.3 MiB | 296.9 MiB | All 500 enabled-mode markers rendered exactly once; all 2,250 large events were delivered with the existing payload elision. Observation-disabled CPU stayed roughly flat (0.13 s to 0.12 s). The controlled publication-order regression also fails original `main` and passes this commit. These are stress-workload measurements, not a general app speedup. Native hosting and deployed-relay performance remain unmeasured. The publish cadence remains one frame per second. No CI timing threshold was added. Generated with Codex Signed-off-by: Sanket Kanjalkar <sanketk@squareup.com> Co-authored-by: Codex <codex@openai.com>