Skip to content

fix(control-ui): measure and decouple slow refreshes#75986

Merged
BunsDev merged 6 commits intomainfrom
meow/control-ui-refresh-timing
May 2, 2026
Merged

fix(control-ui): measure and decouple slow refreshes#75986
BunsDev merged 6 commits intomainfrom
meow/control-ui-refresh-timing

Conversation

@BunsDev
Copy link
Copy Markdown
Member

@BunsDev BunsDev commented May 2, 2026

Summary

  • Add Control UI timing events for tab visible render, refresh scopes, secondary refresh groups, and attributed gateway RPCs.
  • Decouple primary tab feedback from expensive secondary refreshes in Overview, Cron, and Nodes so Sessions/primary panels can render before slower auxiliary calls settle.
  • Harden background refresh attribution so cron.runs returns an explicit ok/error/skipped load outcome, stale Cron results are ignored after tab changes, and Overview/Cron secondary groups record duration plus aggregate status.
  • Add focused UI controller/gateway coverage for RPC attribution, non-blocking refresh behavior, stale guards, controller-derived Cron failure status, and secret-safe failed-RPC timing payloads.
  • Include a one-line Discord test fixture correction from latest main so exact-head check:test-types remains green after rebase.

Fixes #64004.

Security / Performance Audit

  • Security-sensitive surface: Control UI TypeScript, tests, and changelog only. No dependency, workflow, package metadata, secret handling, auth policy, or code-execution changes.
  • RPC timing payloads intentionally record only id, method, ok, durationMs, slow, and errorCode; request params and response payloads are not stored in the event log. Regression coverage uses a config.get request containing a fake token and asserts timing excludes params.
  • Event log storage remains bounded to 250 entries and Overview renders only the top visible subset, preventing unbounded client memory growth from the new telemetry.
  • Primary render path now stays independent from slower secondary panels: Overview secondary work and Cron runs no longer block the primary tab refresh, and Nodes loads primary node data before secondary device/config/approval panels settle.
  • Background work is stale-guarded by per-refresh sequence plus active-tab checks, so late Overview/Cron completions cannot update the wrong tab.
  • cron.runs failures are attributed from the controller's real load outcome instead of promise rejection state, so caught RPC failures record status: "error" while preserving primary Cron tab feedback.

Validation

Rebased head: 84c472c5abd58b66ac6ee5e27f9405a4b08b9b9d.

  • pnpm test ui/src/ui/gateway.node.test.ts ui/src/ui/app-gateway.node.test.ts ui/src/ui/app-settings.refresh-active-tab.node.test.ts ui/src/ui/controllers/sessions.test.ts ui/src/ui/controllers/usage.node.test.ts ui/src/ui/controllers/cron.test.ts src/config/zod-schema.providers.lazy-runtime.test.ts src/cli/plugins-install-persist.test.ts src/cli/plugins-cli.install.test.ts extensions/discord/src/monitor/message-handler.preflight-channel-context.test.ts -- --reporter=dot (189 tests across 4 Vitest shards)
  • pnpm tsgo:test:ui
  • pnpm tsgo:test:src
  • pnpm check:test-types
  • pnpm exec oxfmt --check --threads=1 extensions/discord/src/monitor/message-handler.preflight-channel-context.test.ts CHANGELOG.md src/cli/plugins-install-persist.test.ts src/config/zod-schema.providers.lazy-runtime.test.ts ui/src/ui/app-gateway.ts ui/src/ui/app-settings.refresh-active-tab.node.test.ts ui/src/ui/app-settings.ts ui/src/ui/control-ui-performance.ts ui/src/ui/controllers/cron.test.ts ui/src/ui/controllers/cron.ts ui/src/ui/gateway.node.test.ts ui/src/ui/gateway.ts
  • git diff --check origin/main...HEAD
  • pnpm check:changelog-attributions
  • Testbox OPENCLAW_TESTBOX=1 pnpm check:changed on tbx_01kqm03gynfzpn8248rb32nrb7

Duplicate / Related Triage

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: L maintainer Maintainer-authored PR labels May 2, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 2, 2026

Codex review: needs maintainer review before merge.

Summary
The PR adds Control UI refresh/RPC timing, decouples slow Overview/Cron/Nodes secondary refresh work from primary tab feedback, returns explicit Cron run load status, and updates focused tests plus the changelog.

Reproducibility: yes. #64004 provides concrete Windows Server/npm-global steps and timing logs showing fast sessions.list responses while other Control UI RPCs such as node.list and cron.runs take tens of seconds; current main source still has refresh paths where those calls can overlap tab feedback.

Next step before merge
No repair lane is needed; the remaining action is normal maintainer review and completion of exact-head checks for the open PR.

Security
Cleared: Cleared: the diff adds Control UI telemetry/tests/changelog plus one Discord test fixture correction without dependency, workflow, package, secret-storage, auth-policy, or code-execution changes.

Review details

Best possible solution:

Proceed through maintainer review and exact-head CI for this focused #64004 slice, while leaving the broader responsiveness and polling/churn work to the existing related items.

Do we have a high-confidence way to reproduce the issue?

Yes. #64004 provides concrete Windows Server/npm-global steps and timing logs showing fast sessions.list responses while other Control UI RPCs such as node.list and cron.runs take tens of seconds; current main source still has refresh paths where those calls can overlap tab feedback.

Is this the best way to solve the issue?

Yes. The PR is a narrow maintainable fix for attribution and secondary-refresh isolation, and it avoids folding broader provider, polling, or gateway-churn changes into this patch.

What I checked:

  • Protected active PR state: GitHub API shows the PR is open, unmerged, non-draft, authored by a MEMBER, labeled maintainer, and currently at head 84c472c5abd58b66ac6ee5e27f9405a4b08b9b9d. URL: fix(control-ui): measure and decouple slow refreshes #75986. (84c472c5abd5)
  • Current main still has coupled refresh behavior: On current main, loadOverview awaits one Promise.allSettled group containing primary and secondary loaders, and loadCron awaits loadCronRuns with the primary Cron refresh group, so the PR is not obsolete on main. (ui/src/ui/app-settings.ts:603, a0c3cd68783b)
  • Overview and Cron secondary refreshes are isolated in the PR: The PR head starts secondary Overview work without awaiting it and records its aggregate status later; Cron run history is similarly started in the background with a stale-tab guard before recording timing. (ui/src/ui/app-settings.ts:625, 84c472c5abd5)
  • RPC timing payloads avoid request data: The new timing recorder stores only id, method, ok, duration, slow, and errorCode, while the gateway test sends a fake token in config.get params and asserts params are not included in timing callbacks. (ui/src/ui/control-ui-performance.ts:151, 84c472c5abd5)
  • Focused non-blocking refresh coverage exists: The PR adds tests for tab-visible timing, non-blocking Overview/Cron refresh behavior, Cron failure attribution, rejected background refresh containment, and stale Cron timing suppression. (ui/src/ui/app-settings.refresh-active-tab.node.test.ts:196, 84c472c5abd5)
  • Exact-head checks mostly green with two still running: The GitHub checks API showed broad CI successes on the PR head, including check/test/type/security jobs, with checks-node-core-runtime-infra and Critical Quality (channel-runtime-boundary) still in progress at inspection time. (84c472c5abd5)

Likely related people:

  • steipete: Peter Steinberger has recent current-main maintenance across the Control UI settings/gateway files and adjacent gateway reconnect behavior touched by this PR. (role: recent maintainer and adjacent owner; confidence: high; commits: 1ad50a36ac72, 49e2992be5a9, 8d58ad4c15cd; files: ui/src/ui/app-settings.ts, ui/src/ui/gateway.ts, ui/src/ui/app-gateway.ts)
  • BunsDev: Independent of this PR, prior merged history shows Val Alexander/BunsDev on major Control UI dashboard, settings, and slash-command UX work in the same area. (role: Control UI feature-history contributor; confidence: medium; commits: e697ec273a85, ead8be96fdd6, 2cfb660a9bb8; files: ui/src/ui/app-settings.ts, ui/src/ui/app-gateway.ts, ui/src/ui/gateway.ts)
  • Takhoffman: Tak Hoffman appears in merged Cron UI history for full edit parity, all-jobs run history, routing controls, and adjacent Control UI/gateway work relevant to the Cron refresh surface. (role: Cron UI history contributor; confidence: medium; commits: 77c3b142a966, 254bb7ceeef0, cc5c691f0069; files: ui/src/ui/controllers/cron.ts, ui/src/ui/app-settings.ts, ui/src/ui/app-gateway.ts)
  • joshavant: Recent merged refactors simplified active-tab refresh routing and Cron wrapper behavior around the exact dispatch paths this PR changes. (role: active-tab refresh refactor contributor; confidence: medium; commits: f136a8159cc2, 393c791466fd, d085ceb3f2c5; files: ui/src/ui/app-settings.ts, ui/src/ui/controllers/cron.ts)

Remaining risk / open question:

Codex review notes: model gpt-5.5, reasoning high; reviewed against a0c3cd68783b.

Copy link
Copy Markdown
Member Author

BunsDev commented May 2, 2026

Response to the ClawSweeper review at #75986 (comment):

I rechecked the review finding against the rebased branch and fixed it directly.

What changed after the review:

  • loadCronRuns now returns an explicit ok / error / skipped load status instead of only mutating cronError and resolving.
  • loadCron records control-ui.cron.runs from that controller outcome, so a real caught cron.runs RPC failure is attributed as status: "error" instead of ok.
  • Unexpected rejected background promises remain contained and still record status: "error" without failing the primary Cron tab refresh.
  • Added regression coverage in ui/src/ui/app-settings.refresh-active-tab.node.test.ts for controller-resolved Cron failure status and retained stale-tab/rejection coverage.
  • Added controller coverage in ui/src/ui/controllers/cron.test.ts proving loadCronRuns returns ok on success and error when cron.runs throws after setting cronError.
  • After rebasing onto the latest main, fixed the new Discord test fixture from threadChannel: undefined to threadChannel: null, matching the required DiscordThreadChannel | null contract and clearing exact-head check:test-types.

Security audit:

  • The diff still touches Control UI TypeScript, tests, CHANGELOG.md, and one Discord test fixture correction.
  • No dependency, workflow, package metadata, auth policy, secret storage, network boundary, or code-execution surface changed.
  • RPC timing payloads include method/id/status/duration/error code only; request params and response payloads are intentionally excluded and covered by the fake-token regression test.

Performance audit:

Validation on rebased SHA 84c472c5abd58b66ac6ee5e27f9405a4b08b9b9d:

  • pnpm test ui/src/ui/gateway.node.test.ts ui/src/ui/app-gateway.node.test.ts ui/src/ui/app-settings.refresh-active-tab.node.test.ts ui/src/ui/controllers/sessions.test.ts ui/src/ui/controllers/usage.node.test.ts ui/src/ui/controllers/cron.test.ts src/config/zod-schema.providers.lazy-runtime.test.ts src/cli/plugins-install-persist.test.ts src/cli/plugins-cli.install.test.ts extensions/discord/src/monitor/message-handler.preflight-channel-context.test.ts -- --reporter=dot (189 tests across 4 Vitest shards)
  • pnpm tsgo:test:ui
  • pnpm tsgo:test:src
  • pnpm check:test-types
  • pnpm exec oxfmt --check --threads=1 extensions/discord/src/monitor/message-handler.preflight-channel-context.test.ts CHANGELOG.md src/cli/plugins-install-persist.test.ts src/config/zod-schema.providers.lazy-runtime.test.ts ui/src/ui/app-gateway.ts ui/src/ui/app-settings.refresh-active-tab.node.test.ts ui/src/ui/app-settings.ts ui/src/ui/control-ui-performance.ts ui/src/ui/controllers/cron.test.ts ui/src/ui/controllers/cron.ts ui/src/ui/gateway.node.test.ts ui/src/ui/gateway.ts
  • git diff --check origin/main...HEAD
  • pnpm check:changelog-attributions
  • Testbox OPENCLAW_TESTBOX=1 pnpm check:changed on tbx_01kqm03gynfzpn8248rb32nrb7

@BunsDev BunsDev force-pushed the meow/control-ui-refresh-timing branch from 0c09e6b to 2c49705 Compare May 2, 2026 07:37
@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations gateway Gateway runtime labels May 2, 2026
@BunsDev BunsDev force-pushed the meow/control-ui-refresh-timing branch from 9f2689b to 6ca9e35 Compare May 2, 2026 07:42
@openclaw-barnacle openclaw-barnacle Bot removed the gateway Gateway runtime label May 2, 2026
@BunsDev BunsDev force-pushed the meow/control-ui-refresh-timing branch from 6ca9e35 to bb42ad3 Compare May 2, 2026 07:45
@openclaw-barnacle openclaw-barnacle Bot added the cli CLI command changes label May 2, 2026
@BunsDev BunsDev force-pushed the meow/control-ui-refresh-timing branch from d762848 to d986a33 Compare May 2, 2026 07:52
@openclaw-barnacle openclaw-barnacle Bot removed the commands Command implementations label May 2, 2026
@BunsDev BunsDev force-pushed the meow/control-ui-refresh-timing branch 3 times, most recently from 4f14490 to 26f3b78 Compare May 2, 2026 09:10
@BunsDev BunsDev force-pushed the meow/control-ui-refresh-timing branch from 26f3b78 to 84c472c Compare May 2, 2026 09:28
@openclaw-barnacle openclaw-barnacle Bot added the channel: discord Channel integration: discord label May 2, 2026
@BunsDev BunsDev merged commit 64fcc8a into main May 2, 2026
108 of 109 checks passed
@BunsDev BunsDev deleted the meow/control-ui-refresh-timing branch May 2, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui channel: discord Channel integration: discord cli CLI command changes maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI remains slow although sessions.list returns quickly

1 participant