perf: Move ShowWorkspace CI polling off the UI IPC path - #223
Conversation
PR info was already served from a Rust background cache, but usePrCiStatus still shelled out to `gh pr checks` every 15s via sync Tauri commands, which stuttered ShowWorkspace. Cache CI rollups in the same poller, expose cache-only reads, and run remaining gh force-fetch commands through spawn_blocking. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Drop the leftover dynamic import after switching invalidatePrStatuses to warm both PR info and CI caches in parallel. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
There was a problem hiding this comment.
Same stutter class as #218, but for CI: ShowWorkspace’s 15s gh pr checks was still on the command path.
- Background poller now also caches CI; only shells out when a PR exists for the branch
- UI reads stay cache-only;
pr-statuses-updatedcarriesci_statusesso React Query updates without anothergh
There was a problem hiding this comment.
Force-fetch / panel paths still need gh, but must not stall IPC the way sync commands did (same pattern as gh_create_pr in #217).
get_pr_info_via_gh,get_pr_checks_*, andgh_list_pr_review_threadsnow usespawn_blocking- Force-fetch also warms the background CI cache so the next UI read is immediate
There was a problem hiding this comment.
usePrCiStatus mirrors usePrInfoViaGh: start the Rust poller, listen for cache events, refetch from memory every 15s.
- Removes the ShowWorkspace stutter source (sync
getPrChecksViaGhon interval) invalidatePrStatusesstill force-warms both PR + CI after create-PR mutations
Reduce ShowWorkspace IPC load from inline PR review thread refreshes; CI status already rides the Rust background cache. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Keep gh pr checks off the UI path: the poller refreshes CI every 30s (independently of 60s PR metadata) and usePrCiStatus only reads the cache. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
There was a problem hiding this comment.
CI now has its own 30s cadence (DEFAULT_CI_POLL_INTERVAL), independent of 60s PR metadata.
- Mid-cycle tick calls
refresh_ci_now/poll_ci_only—gh pr checksonly, nogh pr view - UI still only reads
get_cached_pr_ci_status; force-fetchget_pr_checks_via_ghis spawn_blocking + cache warm
Collapse applyPrStatusesToQueryCache args and hydrate CI via listCachedPrCiStatuses during sidebar cache reads. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Warm the Rust PR/CI cache out-of-band via a single fire-and-forget refresh_pr_branch_status call so opening a workspace is not stuck on the next poll tick. Hook tests avoid flaky NAPI createTestRepo. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Satisfy the no-inline-comments lint rule after Biome/cargo fmt. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
| }, [repoPath]); | ||
| if (branchName) { | ||
| void refreshPrBranchStatus(repoPath, branchName); | ||
| } |
There was a problem hiding this comment.
- Workspace open already starts the poller; this queues an immediate branch warm so the first paint is not stuck on a stale 30s/60s tick.
- Same call from
usePrCiStatus— coalesced on the Rust side when both mount together. - Permalink:
treq/src/hooks/useMergeQueueStatus.ts
Lines 160 to 165 in 5fffc89
| inner.branch_refresh_inflight.lock().unwrap().remove(&key); | ||
| }) | ||
| .expect("failed to spawn pr-status-branch-refresh thread"); | ||
| } |
There was a problem hiding this comment.
- One call warms both PR metadata and CI for the opened branch; UI stays on cache reads.
- Fire-and-forget + inflight coalesce so double-mount (PR hook + CI hook) does not spawn two
ghshells. - Permalink:
treq/src-tauri/src/pr_status.rs
Lines 210 to 227 in 5fffc89
| // JS event loop on `gh` (which is what caused test timeouts when | ||
| // a spy was briefly restored to the real invoke). | ||
| treq_lib::pr_status::global().queue_branch_refresh(repo_path, branch_name); | ||
| Ok(Value::Null) |
There was a problem hiding this comment.
- Must return before
ghfinishes:invokeSyncruns on the Node event loop, so a blocking refresh previously timed out Vitest and stuttered the UI path. - Permalink:
treq/crates/treq-napi/src/dispatch.rs
Lines 106 to 114 in 5fffc89
Summary
When a workspace is opened, queue a single out-of-band PR info + CI checks refresh so the Rust background cache is warmed before the next poll tick. The UI keeps reading cache-only; the user should not see stale PR/CI state after switching workspaces.
Changes
PrStatusManager::queue_branch_refresh/refresh_branch_now— one call fetches PR + CI for a branch; queue is fire-and-forget and coalesces in-flight(repo, branch).refresh_pr_branch_statusreturns immediately (does not block the JS event loop ongh).usePrInfoViaGhandusePrCiStatuscallrefreshPrBranchStatuson mount when a branch is present.Test plan
cargo test --lib pr_statusnpm run test:run -- test/integration/useMergeQueueStatus.test.tsnpm run test:run -- src/components/CiStatusIndicator.test.tsxci-status-indicatorsuccess / failure / pending screenshots