Cache subagent read snapshots on gateway hot paths#88166
Conversation
|
Codex review: needs maintainer review before merge. Reviewed May 29, 2026, 7:59 PM ET / 23:59 UTC. Summary PR surface: Source +358, Tests +681. Total +1039 across 15 files. Reproducibility: Do we have a high-confidence way to reproduce the issue? Partly: the PR body gives a concrete CodeClaw Docker profiling path and before/after metrics, and the source path is clear, but I did not rerun the live profiler during this read-only review. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this cache after maintainer review accepts the invalidation coverage and required CI, preserving the focused snapshot, lifecycle, and gateway row-context tests. Do we have a high-confidence way to reproduce the issue? Do we have a high-confidence way to reproduce the issue? Partly: the PR body gives a concrete CodeClaw Docker profiling path and before/after metrics, and the source path is clear, but I did not rerun the live profiler during this read-only review. Is this the best way to solve the issue? Is this the best way to solve the issue? Yes, with maintainer review: the implementation moves repeated gateway/session reads to operation-scoped immutable snapshots rather than adding scattered per-call caches, but the invalidation paths deserve human scrutiny before merge. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 582aa1ceb2b1. Label changesLabel justifications:
Evidence reviewedPR surface: Source +358, Tests +681. Total +1039 across 15 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
galiniliev
left a comment
There was a problem hiding this comment.
This PR caches immutable subagent registry read snapshots and reuses operation-scoped gateway session row context so sessions.list, sessions.get, and row loading stop rebuilding the same subagent indexes on hot paths. It matters because the touched surface is session-state sensitive: missed invalidation could show stale child-session or terminal-run state.
LOC: +1148/-109 (15 files)
By: Eduardo Piva (@efpiva, acct 2014-01-13) | OpenClaw: 22 PRs, 1 issue, 12 commits/12mo | GitHub: 14 commits, 22 PRs, 1 issue, 0 reviews
Assignment: assigned to @galiniliev at 2026-05-30 05:25 UTC; fresh at review time.
Findings: no code findings.
One merge blocker remains outside the patch review: live CI is UNSTABLE because checks-node-core-fast failed with timeouts in src/security/audit-sandbox-browser.test.ts:79 and src/security/audit-sandbox-browser.test.ts:105. That file is outside the touched surface, so I would rerun or otherwise clear that check before landing, but I do not see evidence that this PR caused it.
Review notes:
- The cache shape looks consistent with the hot-path policy: disk snapshots are keyed by registry file signature, memory snapshots by
subagentRegistryMemoryVersion, and the merged read snapshot is frozen before reuse (src/agents/subagent-registry-state.ts:70,src/agents/subagent-registry.store.ts:309). - In-place mutation invalidation is covered by
persistSubagentRuns()version bumps and the explicit dirty-before-await lifecycle path (src/agents/subagent-registry.ts:264,src/agents/subagent-registry-lifecycle.ts:1105). - The gateway side keeps the optimization operation-scoped: list rows share one
SessionListRowContext, single-row loads only build the full subagent read index past the child-candidate threshold, and fallback paths preserve existing child-session semantics (src/gateway/session-utils.ts:676,src/gateway/session-utils.ts:711,src/gateway/session-utils.ts:2279,src/gateway/session-utils.ts:2560).
Best-fix verdict: this is the right fix shape for the reported hot path. It moves prepared read facts earlier and reuses immutable snapshots instead of adding scattered per-call caches.
Provenance: N/A for a performance/cache improvement; recent related main history includes prior gateway/subagent read-cache work (fix(gateway): cache single session row child indexes, fix(agents): reuse cached subagent registry reads), but I did not identify a discrete regression-introducing PR.
Proof checked: PR body's focused Vitest/check evidence, live CI status, ClawSweeper review, scoped AGENTS.md for src/agents and src/gateway, gitcrawl thread lookup, git diff --check origin/main...origin/pr/88166 passed. I did not rerun the Vitest suite locally.
|
Closing this as superseded by #88260, which landed in 5374c7a. That replacement moves the subagent registry off the JSON/disk-signature path and into SQLite-backed state, so caching legacy disk snapshots is no longer the direction we want to maintain. If we revisit this hot path, the follow-up should optimize the SQLite/per-agent-state query path rather than add another file-registry cache layer. Thanks @efpiva for the detailed profiling and tests here; the performance evidence was useful context for the replacement work. |
Summary
sessions.list,sessions.get, and gateway row loading while preserving existing child-session filtering semantics.Verification
node scripts/run-vitest.mjs src/gateway/session-utils.perf.test.ts src/gateway/session-utils.single-row-cache.test.ts src/gateway/session-utils.subagent.test.ts src/agents/subagent-registry-read-context.test.ts src/agents/subagent-registry.persistence.test.tsnode scripts/run-vitest.mjs src/agents/subagent-registry-lifecycle.test.ts src/agents/subagent-registry.persistence.test.ts src/agents/subagent-registry-read-context.test.ts src/gateway/session-utils.single-row-cache.test.ts src/gateway/session-utils.perf.test.ts src/gateway/session-utils.subagent.test.tspnpm check:changed.agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --prompt-file /tmp/openclaw-codeclaw-pr-review-notes.mdorigin/mainfetch: clean, no accepted/actionable findings.Real behavior proof
Behavior addressed: Repeated gateway/session hot-path reads rebuilt subagent registry snapshots, cloned persisted run maps, and rebuilt full subagent read indexes; the patch caches immutable read snapshots and shares row-scoped read context while preserving subagent/session row behavior.
Real environment tested: CodeClaw
codeclaw-triageDocker deployment with the triage named volumes preserved. Evidence used a pinned comparison base plus identical gated hotpath instrumentation for the before and after builds.Exact steps or command run after this patch: Built OpenClaw tarballs for before/after evidence branches, rebuilt and force-recreated
codeclaw-triagefor each build, ran a 10-minute warmup, enabled gated hotpath profiling for a 1-hour measurement window, then disabled profiling. The patched container was left running afterward for continued validation.Evidence after fix: Sanitized before/after evidence showed:
subagent.registry.readIndextotal profiled time:103.488msbefore ->45.641msafter (-55.9%).gateway.session.childIndextotal profiled time:178.942msbefore ->82.271msafter (-54.0%).subagent.registry.cloneMaptotal profiled time:3682.616msbefore ->2253.583msafter (-38.8%).2453.1 MiB->2454.3 MiB; primary gateway RSS moved712.3 MiB->601.5 MiB.Observed result after fix: The patched CodeClaw container stayed running with restart count 0 and the patched OpenClaw build installed. Profiling was disabled after measurement so the container could continue running without accumulating profile logs.
What was not tested: Full CI was not run locally. Heap snapshots and CPU profiles were intentionally not collected. The 1-hour CodeClaw evidence was captured before the final Codex-review stale-cache fix; that follow-up fix only invalidates in-memory snapshots before an await and was covered by focused tests plus
pnpm check:changed, not by rerunning another 1-hour CodeClaw evidence window.