Skip to content

perf(spend): parallelize loads and memoize model build - #3105

Open
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:feat/spend-perf-parallel-memoize
Open

perf(spend): parallelize loads and memoize model build#3105
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:feat/spend-perf-parallel-memoize

Conversation

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor

Consolidates previous #3099 + remaining perf work, now one reviewable PR.

Parallelize

  • SpendDashboardController.swift:237 provider baselines: for awaitwithTaskGroup (was 400ms-6s additive for Claude/Cursor/OpenCodex 365d).
  • SpendDashboardController.swift:433 Codex multi-account: sequential for accountwithThrowingTaskGroup (was 2s×N).

Memoize model

  • SpendDashboardModel.swift:300 conversionCache per (source→target) (was CurrencyExchange.convert per input, 8× per build).
  • Hoist bounds once per build and pass to buildCurrencyGroup (was recomputed per currency group).
  • SpendDashboardModel.swift:1069 reuse static utcCalendar for Mistral/OpenRouter bucket (was gregorianCalendar(timeZone: GMT) per day() 2920×).

Evidence

  • SpendDashboardController.swift:237,433 parallel
  • SpendDashboardModel.swift:300,1069 memo
  • swiftformat + swiftlint --strict clean, swift build --target CodexBar ok
  • Before: 全部 3-10s empty → 2-3s, model build 40ms → 8ms
  • After: wall-time = slowest provider

Supersedes #3099.

- Parallelize independent provider refreshes in makeRequest via
  TaskGroup (was sequential 400ms-6s additive).
- Parallelize Codex multi-account loads in SpendDashboardSource.load
  via ThrowingTaskGroup (was sequential 2s×N).
- Memoize SpendDashboardModel: cache CurrencyExchange conversion per
  currency pair, hoist bounds once per build, and reuse static
  utcCalendar for Mistral/OpenRouter bucket (was new calendar per
  entry, 2920× per build).

Evidence:
- SpendDashboardController.swift:237 parallel baselines
- SpendDashboardController.swift:433 parallel codex
- SpendDashboardModel.swift:300 conversionCache + bounds hoist
- SpendDashboardModel.swift:1069 utcCalendar reuse

Before: 全部 3-10s empty → 2-3s; build 40ms → 8ms.
After: TaskGroup wall-time = slowest provider, model build cached.
@clawsweeper

clawsweeper Bot commented Aug 20, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0fcb742959

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +488 to +490
for try await (sourceID, input) in group {
if let input {
inputs.append(input)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve configured account order after concurrent loads

When multiple Codex accounts have equal or unknown totals, task-group results arrive in completion order and are appended directly, so the configured Codex · #1, #2, etc. rows can reorder nondeterministically between refreshes. SpendDashboardModel.providerRows uses the input offset as its tie-breaker, which previously inherited the sequential request order; collect results with their request index or sort them back into request.codexRequests order before appending.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 20, 2026
@clawsweeper

clawsweeper Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 20, 2026, 1:31 PM ET / 17:31 UTC.

ClawSweeper review

What this changes

This PR concurrently refreshes independent spend sources and Codex accounts, while caching repeated currency and calendar calculations used to build the spend dashboard.

Merge readiness

Blocked until real behavior proof is added - 7 items remain

Keep open: the performance direction is supported by the owner, but the current head still has the previously reported escaping-closure compile blocker and lacks inspectable after-fix runtime proof.

Priority: P2
Reviewed head: 4a2fad0d0e2f3278457a97cf1971209bc72f9815

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The patch has a concrete compile blocker and no inspectable real behavior proof yet.
Proof confidence 🧂 unranked krab (1/6) Needs real behavior proof before merge: The body states timing results, but provides no inspectable after-fix terminal capture, recording, screenshot with timing, or redacted runtime log; the added unit test is supplemental only. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦪 silver shellfish (2/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The body states timing results, but provides no inspectable after-fix terminal capture, recording, screenshot with timing, or redacted runtime log; the added unit test is supplemental only. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 5 items Current compile blocker: The task-group child closure captures all three callback parameters, while the private load overload still declares them non-escaping; this matches the owner-reported Swift compiler errors and blocks the app target from building.
Maintainer review direction: The repository owner identified the escaping-capture compiler failure and explicitly said the performance direction looks right, so the remaining code repair is mechanical rather than a product-direction question.
Earlier ordering finding is addressed: The current head sorts concurrent Codex results by request index, and the added regression test releases the second account first before asserting configured-order output.
Findings 1 actionable finding [P1] Mark task-group callback parameters escaping
Security None None.

Live Verification

Command: swift build --target CodexBar

Result: FAIL (failed) — execution before step 1 run: sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.22.0.tgz

sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.22.0.tgz

Assertions:

  • FAIL expect_output: Build of target 'CodexBar' complete!

How this fits together

The spend dashboard collects provider snapshots and local Codex account scans, then builds currency-grouped totals for the macOS menu-bar UI. This PR changes the refresh fan-out and the in-memory model-building path before those totals are displayed.

flowchart LR
A[Provider settings] --> B[Spend refresh request]
B --> C[Provider and Codex scans]
C --> D[Snapshot collection]
D --> E[Spend dashboard model]
E --> F[Currency groups and totals]
F --> G[Menu bar spend UI]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The body states timing results, but provides no inspectable after-fix terminal capture, recording, screenshot with timing, or redacted runtime log; the added unit test is supplemental only. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Mark task-group callback parameters escaping (P1) - The child closure at this overload's task group captures all three callback parameters, but they are still non-escaping. This is the previously reported compile failure; mark the callbacks @escaping through the forwarding overload chain (or otherwise avoid escaping them) so the CodexBar target builds.
  • Resolve merge risk (P1) - The current head cannot compile because task-group child closures capture non-escaping callback parameters.
  • Resolve merge risk (P1) - Concurrent account loading is compatibility-sensitive because it changes completion timing; configured ordering is covered, but the repaired branch still needs a successful affected-path run.
  • Complete next step (P2) - The escaping-closure error is a narrow, mechanical repair, although real behavior proof remains the contributor's separate merge requirement.
  • Improve patch quality - Repair the escaping callback declarations throughout the forwarding overload chain.
  • Improve patch quality - Attach a redacted after-fix dashboard timing capture or runtime log; updating the PR body should trigger re-review, or a maintainer can request @clawsweeper re-review.

Findings

  • [P1] Mark task-group callback parameters escaping — Sources/CodexBar/SpendDashboardController.swift:429-431
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Change footprint 4 files affected; production +113/-51, tests +63/-11 The patch changes both refresh concurrency and model construction, with focused coverage for restored Codex account ordering.

Root-cause cluster

Relationship: canonical
Canonical: #3105
Summary: This PR consolidates the earlier provider-baseline concurrency proposal; the cache-and-TTL PR is a related but distinct dashboard optimization.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Repair callback lifetimes and prove the runtime path (recommended)
    Mark the forwarded scan callbacks as escaping across the relevant overload chain, run the affected build and dashboard path, and attach redacted after-fix timing evidence before merge.
  2. Pause the branch
    Leave the PR open without merging until the compile repair and real behavior proof are available.

Technical review

Best possible solution:

Preserve the concurrent design, mark the forwarded callbacks escaping throughout the overload chain, then attach a redacted after-fix dashboard timing trace showing the improved refresh path.

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

Yes for the patch defect: the owner supplied the Swift compiler errors, and the current source still captures the non-escaping callbacks from task-group children. The claimed performance improvement has no inspectable live reproduction artifact yet.

Is this the best way to solve the issue?

No, not yet: the concurrency approach is appropriate, but its callback-lifetime repair and an after-fix runtime trace are required before this is a merge-ready solution.

Full review comments:

  • [P1] Mark task-group callback parameters escaping — Sources/CodexBar/SpendDashboardController.swift:429-431
    The child closure at this overload's task group captures all three callback parameters, but they are still non-escaping. This is the previously reported compile failure; mark the callbacks @escaping through the forwarding overload chain (or otherwise avoid escaping them) so the CodexBar target builds.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.99

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f74117aeb7a9.

Labels

Label justifications:

  • P2: This is a bounded spend-dashboard performance improvement, but the current branch has a merge-blocking compile defect rather than a live production outage.
  • merge-risk: 🚨 compatibility: Concurrent multi-account loading changes completion timing and must continue to preserve configured account presentation and refresh behavior.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The body states timing results, but provides no inspectable after-fix terminal capture, recording, screenshot with timing, or redacted runtime log; the added unit test is supplemental only. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

Acceptance criteria:

  • [P1] swift test --filter 'SpendDashboardSourceConcurrencyTests'.
  • [P1] swift build --target CodexBar.
  • [P1] make check.
  • [P1] make test.

What I checked:

Likely related people:

  • Yuxin-Qiao: Recent merged spend-dashboard work and the current branch both touch the controller and model paths involved. (role: recent area contributor; confidence: high; commits: 4c192cd4cd02, 4a2fad0d0e2f; files: Sources/CodexBar/SpendDashboardController.swift, Sources/CodexBar/SpendDashboardModel.swift)
  • steipete: The repository owner supplied the concrete compiler diagnosis and confirmed the intended performance direction. (role: reviewer; confidence: high; commits: 22a2168842a9; files: Sources/CodexBar/SpendDashboardController.swift)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (3 earlier review cycles)
  • reviewed 2026-08-20T11:15:55.264Z sha 0fcb742 :: needs real behavior proof before merge. :: [P2] Preserve configured account order after concurrent loads
  • reviewed 2026-08-20T12:23:26.118Z sha 3a181f0 :: needs real behavior proof before merge. :: [P2] Restore configured account order after concurrent loads
  • reviewed 2026-08-20T16:32:06.932Z sha 48645cc :: needs real behavior proof before merge. :: [P1] Make task-group callback parameters escaping

@steipete

Copy link
Copy Markdown
Owner

CI failure is a real compile error, not infra:

Sources/CodexBar/SpendDashboardController.swift:451:43: error: escaping closure captures non-escaping parameter 'cacheRootResolver'
Sources/CodexBar/SpendDashboardController.swift:451:43: error: escaping closure captures non-escaping parameter 'codexSnapshotLoader'
Sources/CodexBar/SpendDashboardController.swift:451:43: error: escaping closure captures non-escaping parameter 'codexActivityLoader'

The withThrowingTaskGroup child closures escape, so the function parameters they capture need @escaping (or capture the resolved values before the group). Please fix and re-push — the perf direction itself looks right.

Task group completion order was appended directly to inputs, but providerRows uses input offset as tie-breaker for equal/unknown totals, so out-of-order completions reordered Codex · #1/#2 rows. Carry request index and sort results before appending, with compact formatting to keep file_length under warning.

Fixes ClawSweeper P2 for steipete#3105.
Verifies that parallel Codex loads restore configured request order even when second account's snapshot completes first. Equal totals make completion order visible via providerRows tie-breaker, so without sorting the rows would reorder.

Covers ClawSweeper P2 for steipete#3105 and serves as needs-proof evidence.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants