perf(desktop): parallelize git status checks and optimize file scanning#679
perf(desktop): parallelize git status checks and optimize file scanning#679
Conversation
The getStatus procedure was running 7-9 git commands sequentially every 2.5s, plus reading all untracked files one at a time. This could cause UI lag. Changes: - Run branch comparison, tracking status, and numstat operations in parallel - Limit untracked file line counting to 50 files max (100KB each) - Process file reads in parallel batches of 10 - Add staleTime and disable background refetch to prevent request overlap 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Warning Rate limit exceeded@Kitenite has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 32 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughRefactored the Git status operation to parallelize multiple queries—branch comparison, tracking status, and numstat computations—along with batched untracked line counting. Added query caching options to the Changes view to reduce UI flicker and prevent concurrent refetches. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (1)
56-59: Misleading comment aboutrefetchIntervalInBackground.The comment on line 58 states this option cancels in-flight requests, but
refetchIntervalInBackground: falseonly pauses interval-based refetching when the window is not focused—it does not cancel existing requests. Consider updating the comment to accurately describe the behavior.📝 Suggested comment fix
// Keep previous data while refetching to prevent UI flicker staleTime: 2000, - // Ensure we don't overlap requests - cancel in-flight when new one starts + // Pause interval refetching when window is in background refetchIntervalInBackground: false,apps/desktop/src/lib/trpc/routers/changes/status.ts (1)
176-178: Consider minimal logging for debugging purposes.Per coding guidelines, errors should not be silently swallowed. While skipping unreadable files is the correct behavior here, adding debug-level logging would help diagnose issues in development without impacting performance.
💡 Optional: Add debug logging
} catch { - // Skip files that fail validation or reading + // Skip files that fail validation or reading (expected for deleted/inaccessible files) + console.debug(`[changes/status] Skipped untracked file: ${file.path}`); }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/desktop/src/lib/trpc/routers/changes/status.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsxapps/desktop/src/lib/trpc/routers/changes/status.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsxapps/desktop/src/lib/trpc/routers/changes/status.ts
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsxapps/desktop/src/lib/trpc/routers/changes/status.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsxapps/desktop/src/lib/trpc/routers/changes/status.ts
🧬 Code graph analysis (1)
apps/desktop/src/lib/trpc/routers/changes/status.ts (3)
apps/desktop/src/lib/trpc/routers/changes/utils/parse-status.ts (1)
parseGitStatus(31-74)apps/desktop/src/lib/trpc/routers/changes/utils/apply-numstat.ts (1)
applyNumstatToFiles(5-24)apps/desktop/src/shared/changes-types.ts (1)
ChangedFile(22-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (3)
apps/desktop/src/lib/trpc/routers/changes/status.ts (3)
32-44: Good parallelization of independent operations.The Promise.all pattern correctly runs independent operations concurrently. The destructuring intentionally ignores the void results from the mutation functions (
applyNumstatToFiles,applyUntrackedLineCount). This is a valid pattern, though a brief inline comment clarifying that the last three operations mutate their inputs in place would improve readability for future maintainers.
149-154: Well-structured performance constants.Good extraction of magic numbers into named constants with clear documentation. The values are sensible for the use case.
160-181: Solid batched concurrency implementation.The sequential batch processing with
Promise.alleffectively limits concurrent file operations to 10 at a time, preventing resource exhaustion. The early slice at line 161 ensures the 50-file cap is applied upfront. Good balance between parallelism and resource management.
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
…ng (#679) * perf(desktop): parallelize git status checks and optimize file scanning The getStatus procedure was running 7-9 git commands sequentially every 2.5s, plus reading all untracked files one at a time. This could cause UI lag. Changes: - Run branch comparison, tracking status, and numstat operations in parallel - Limit untracked file line counting to 50 files max (100KB each) - Process file reads in parallel batches of 10 - Add staleTime and disable background refetch to prevent request overlap
Summary
Promise.all()instead of sequentialawaitsstaleTimeand disable background refetch on the client to prevent UI flicker and request overlapContext
The
getStatustRPC procedure runs every 2.5 seconds to poll for git changes. Previously it ran 7-9 git commands sequentially plus read all untracked files one at a time, which could cause UI lag especially with many files.Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.