Skip to content

Fix git-metadata probe CPU storm: lock-free hex + concurrency cap - #5400

Closed
austinywang wants to merge 2 commits into
mainfrom
feat-git-probe-cpu-spikes
Closed

austinywang wants to merge 2 commits into
mainfrom
feat-git-probe-cpu-spikes

Conversation

@austinywang

@austinywang austinywang commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Two fixes for the sidebar git-metadata probe CPU storm that spikes the cmux app past 100% CPU and beachballs under many workspaces (#4639). Diagnosed from a live sample of the production app: gitTrackedChangesSnapshot and gitIndexSnapshot dominated the profile, running in parallel across ~36 panels.

1. Lock-free hex encoder. gitIndexSnapshot formatted every 20-byte object ID with String(format: "%02x", $0), which acquires a process-global locale lock (localeconv_l / os_unfair_lock) on each call. Across thousands of index entries and dozens of probes running in parallel, that lock turned into a multi-core CPU storm. The four hex sites (object ID, index checksum, file signature, FNV content signature) now use a table-based encoder with byte-identical lowercase output.

2. Concurrency cap. beginWorkspaceGitMetadataProbeAttempt spawned one detached .utility task per tracked panel with no global cap, so a burst (workspace restore, the 5-minute fallback refresh, a file-watch flurry) parsed dozens of .git/index files at once. New GitProbeConcurrencyLimiter (a bounded async gate that resumes waiters FIFO) wraps the single parse choke point, TabManager.initialWorkspaceGitMetadataSnapshot, capped at 4. Excess probes suspend until a slot frees instead of storming every core.

Tests (CmuxGit, Swift Testing):

  • HexEncodingTests: the encoder matches String(format:) across all 256 byte values, the ArraySlice/Data.suffix call shapes, and full-width UInt64. The existing index parser tests pass unchanged, confirming byte-identical output.
  • GitProbeConcurrencyLimiterTests: never exceeds the cap under 60 concurrent tasks, strictly serializes at ceiling 1, and clamps a non-positive ceiling.

Not in this PR: the browser.eval / browser.wait main-thread beachball (#4363) is a separate browser-automation-wide threading refactor (~35 call sites route WebView access through the shared v2BrowserWithPanel helper under WKWebView main-actor constraints). Tracked as a follow-up.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Low Risk
Performance-only changes to git metadata parsing and probe scheduling; behavior is preserved via byte-identical hex output and tests, with no auth or data-model changes.

Overview
Addresses multi-core CPU spikes from parallel sidebar git-metadata probes (issue #4639) with two targeted changes.

Index parsing no longer uses per-byte String(format: "%02x") / %016llx when building object IDs, checksums, file signatures, and FNV content hashes. Those call sites now use a table-based lowercaseHexString so hex output stays the same without hitting the process-global locale lock under heavy parallel index reads.

Probe scheduling adds a shared GitProbeConcurrencyLimiter (FIFO async gate, minimum ceiling 1) and wraps TabManager.initialWorkspaceGitMetadataSnapshot at 4 concurrent parses so workspace restore, fallback refresh, or watch bursts cannot run unbounded .git/index parses across every panel.

New Swift Testing suites assert the encoder matches printf for all byte shapes used in production and that the limiter respects its cap, serializes at 1, and clamps invalid ceilings.

Reviewed by Cursor Bugbot for commit e1677a7. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Fixes CPU spikes from git-metadata probes by removing a locale-locked hex path and capping concurrent index parses. Keeps the app responsive during workspace restores and file-watch bursts.

  • Bug Fixes

    • Replaced String(format: "%02x") with a lock-free hex encoder in CmuxGit for object IDs, index checksum, file signature, and FNV content signature. Output is byte-identical.
    • Added GitProbeConcurrencyLimiter and routed TabManager.initialWorkspaceGitMetadataSnapshot through it (cap: 4) to avoid dozens of parallel .git/index parses.
  • Tests

    • Added tests for hex encoder equivalence and limiter behavior (cap enforcement, serialize at 1, clamp non-positive).

Written for commit e1677a7. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Performance
    • Enhanced git repository metadata operations to efficiently handle concurrent checks without resource saturation.
    • Optimized git index data parsing with improved encoding for faster performance.

austinywang and others added 2 commits June 4, 2026 16:28
…ee hex encoder

gitIndexSnapshot formatted every 20-byte object ID via String(format: "%02x", $0),
which takes a process-global locale lock (localeconv_l / os_unfair_lock) on every
call. Across thousands of index entries and many workspace panels probing in
parallel, that lock turned git-metadata probes into a multi-core CPU storm
(#4639).

A table-based encoder produces byte-identical lowercase hex, allocation-light and
lock-free. Applies to the four hex sites: per-entry object ID, index checksum,
index file signature, and the FNV content signature. Verified equivalent across
all 256 byte values, ArraySlice/Data.suffix call shapes, and full-width UInt64;
the existing index parser tests still pass unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
beginWorkspaceGitMetadataProbeAttempt spawns one detached .utility task per
tracked panel with no global concurrency cap. A burst (workspace restore, the
5-minute fallback refresh, or a flurry of file-watch events) schedules one probe
per panel at once; with dozens of panels that parses dozens of .git/index files
in parallel and saturates every core
(#4639).

Add GitProbeConcurrencyLimiter (a bounded async gate that resumes waiters FIFO)
in CmuxGit and route the single parse choke point,
TabManager.initialWorkspaceGitMetadataSnapshot, through it capped at 4. Excess
probes suspend until a slot frees instead of storming every core. Unit tests
cover the cap under load, strict serialization at ceiling 1, and clamping a
non-positive ceiling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 4, 2026 11:42pm
cmux-staging Building Building Preview, Comment Jun 4, 2026 11:42pm

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces backpressure control for concurrent git metadata probes and optimizes hex string generation in git index parsing. A new GitProbeConcurrencyLimiter actor restricts parallel probe parse operations, while a table-based hex encoder replaces inefficient String(format:) calls. The limiter integrates into TabManager with a cap of 4 concurrent probes, and comprehensive tests validate both components.

Changes

Concurrency Limiting and Hex Encoding Optimization

Layer / File(s) Summary
Concurrency Limiter Actor
Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift
New public actor that clamps maxConcurrent to a minimum of 1, maintains available slot count and FIFO continuation queue, exposes run method that acquires a slot, executes async work, and reliably releases the slot with fair FIFO resumption.
Hex Encoding Utility and Migration
Packages/CmuxGit/Sources/CmuxGit/Parsing/GitMetadataService+Index.swift
Introduces table-driven lowercaseHexString utility, then replaces four git index parsing sites—object ID, index checksum, content signature hash, and file signature—from per-byte String(format:) mapping to the new efficient encoder.
TabManager Integration
Sources/TabManager.swift
Adds private gitProbeLimiter property with maxConcurrent: 4, then wraps initialWorkspaceGitMetadataSnapshot metadata fetch inside limiter.run to throttle concurrent probe calls.
Concurrency Limiter Tests
Packages/CmuxGit/Tests/CmuxGitTests/GitProbeConcurrencyLimiterTests.swift
Test suite with ConcurrencyTracker helper actor verifying that limiter with maxConcurrent: 3 caps peak concurrency at 3 across 60 tasks, maxConcurrent: 1 enforces strict serialization, and maxConcurrent: 0 is clamped to 1.
Hex Encoding Tests
Packages/CmuxGit/Tests/CmuxGitTests/HexEncodingTests.swift
Validates lowercaseHexString behavior against String(format:) across all UInt8 values, fixed-width sequences, empty input, slices, and big-endian UInt64 encoding.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A limiter fair with FIFO grace,
Keeps git probes from quickening pace.
Hex strings now dance through table-land,
No format strings left—efficiency's hand!
Tests validate the concurrent flow,
Where backpressure helps performance grow.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (3 errors, 1 warning)

Check name Status Explanation Resolution
Cmux Swift Actor Isolation ❌ Error nonisolated function initialWorkspaceGitMetadataSnapshot accesses MainActor-isolated property gitProbeLimiter, violating Swift 6 actor isolation rules. Mark gitProbeLimiter as nonisolated (it's an Actor, so self-isolated), or remove nonisolated from initialWorkspaceGitMetadataSnapshot.
Cmux Algorithmic Complexity ❌ Error GitProbeConcurrencyLimiter (line 62) uses Array.removeFirst() for a FIFO queue handling ~1000 workspace probes, making each release O(n) instead of O(1), violating batch-action complexity rules. Use Deque or circular-buffer for O(1) dequeue, or add benchmark showing O(n) queue overhead acceptable for 1000 workspaces.
Cmux Full Internationalization ❌ Error New user-facing strings sidebar.activeTabIndicator.leftRail and sidebar.activeTabIndicator.solidFill lack translations for 16 of 20 supported locales in Resources/Localizable.xcstrings. Add translations for all 20 locales (ar, bs, da, de, es, fr, it, km, nb, pl, pt-BR, ru, th, tr, zh-Hans, zh-Hant) in Resources/Localizable.xcstrings for both sidebar.activeTabIndicator strings.
Docstring Coverage ⚠️ Warning Docstring coverage is 42.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely summarizes the two main changes: a lock-free hex encoder and a concurrency cap for git probes, directly addressing the CPU storm issue.
Description check ✅ Passed The description covers all required template sections: detailed summary of what changed and why (two fixes with technical depth), comprehensive testing approach with test suite names, and a checklist with items marked. Demo video is not applicable for performance fixes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Blocking Runtime ✅ Passed PR introduces no blocking synchronization. GitProbeConcurrencyLimiter uses async continuations; hex encoder replaces blocking String(format:) with lock-free version.
Cmux No Hacky Sleeps ✅ Passed Check applies only to non-Swift files (TypeScript, JavaScript, shell, build/runtime scripts). All PR changes are Swift files. Swift timing primitives are covered by separate check.
Cmux Swift Concurrency ✅ Passed PR introduces modern Swift concurrency (actor-based limiter with async/await, withCheckedContinuation) with no legacy Dispatch queues, Combine, completion handlers, or fire-and-forget Tasks.
Cmux Swift @Concurrent ✅ Passed The GitProbeConcurrencyLimiter.run method is correctly actor-isolated with @Sendable closure parameter, providing proper concurrency boundary for CPU-heavy git parsing work.
Cmux Swift File And Package Boundaries ✅ Passed New 65-line actor placed in SwiftPM package with tests; existing files receive minor additions under size thresholds; clear single responsibilities; feature properly extracted from app target.
Cmux Swift Logging ✅ Passed No logging violations found. All 5 changed files contain no print, debugPrint, dump, NSLog, or ad-hoc file/stdout logging in production code.
Cmux User-Facing Error Privacy ✅ Passed No user-facing error messages, alerts, or sensitive information exposed in new code. Changes are internal implementation details (concurrency limiter, hex encoding) and developer-only tests.
Cmux Swiftui State Layout ✅ Passed PR only adds private GitProbeConcurrencyLimiter property to existing TabManager; no new @Published/@observable state or SwiftUI layout violations introduced.
Cmux Architecture Rethink ✅ Passed Uses Swift actor concurrency with clear ownership and FIFO invariant; lock-free hex removes actual lock; no timing repairs, observers, or side-channels.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds no NSWindow, NSPanel, NSWindowController, or SwiftUI Window/WindowGroup. Changes are concurrency limiting and hex encoding—no new standalone windows.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-git-probe-cpu-spikes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes the sidebar git-metadata CPU storm (issue #4639) with two targeted changes: a lock-free table-based hex encoder replaces String(format: "%02x") on every index-entry object ID, eliminating the process-global locale lock contention under parallel probes, and a new GitProbeConcurrencyLimiter actor gates initialWorkspaceGitMetadataSnapshot to at most 4 concurrent .git/index parses.

  • Lock-free hex encoder (GitMetadataService+Index.swift): four String(format:) call sites replaced with a 16-entry byte lookup table; output is byte-identical and confirmed by exhaustive tests across all 256 values, the 20-byte object-ID shape, and the UInt64 big-endian path.
  • Concurrency limiter (GitProbeConcurrencyLimiter.swift, TabManager.swift): FIFO actor-based gate capped at 4 admits probes one slot at a time; slot accounting is balanced (direct hand-off on release); nonisolated access in TabManager is safe because the limiter is a let constant of an actor type.

Confidence Score: 5/5

Safe to merge; changes are performance-only with byte-identical observable behavior, fully covered by new tests, and do not touch auth, data models, or user-facing surfaces.

Both changes are narrowly scoped: the hex encoder is a pure algorithmic substitution with identical output verified exhaustively, and the concurrency limiter's slot accounting is correct. The only known gaps — the withCheckedContinuation cancellation hole and the unused maxConcurrent property — were flagged in prior review threads and do not affect correctness under normal operation.

No files require special attention beyond the items already discussed in prior review threads on GitProbeConcurrencyLimiter.swift.

Important Files Changed

Filename Overview
Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift New FIFO actor-based concurrency gate; slot accounting is correct, but withCheckedContinuation does not honour Swift task cancellation (already flagged in a prior thread) and maxConcurrent is stored but never read after init (also previously flagged)
Packages/CmuxGit/Sources/CmuxGit/Parsing/GitMetadataService+Index.swift Replaces four String(format:) hot-path call sites with a table-based lock-free encoder; byte-identical output verified by tests; big-endian UInt64 encoding is arithmetically correct
Sources/TabManager.swift Adds a shared GitProbeConcurrencyLimiter and wraps initialWorkspaceGitMetadataSnapshot in it; let property is safely accessible from the existing nonisolated context; logic refactoring is semantically equivalent to the original
Packages/CmuxGit/Tests/CmuxGitTests/GitProbeConcurrencyLimiterTests.swift Three Swift Testing cases cover the cap, serialization at ceiling 1, and clamping of non-positive values; uses Task.yield() within the body to allow cooperative interleaving while the limiter's own accounting bounds concurrency
Packages/CmuxGit/Tests/CmuxGitTests/HexEncodingTests.swift Thorough encoder equivalence tests covering all 256 byte values, 20-byte object-ID width, empty input, ArraySlice/Data.suffix shapes, and the full-width UInt64 big-endian hash path

Sequence Diagram

sequenceDiagram
    participant TM as TabManager (nonisolated)
    participant L as GitProbeConcurrencyLimiter (actor)
    participant GMS as GitMetadataService

    TM->>L: await gitProbeLimiter.run
    alt slot available
        L->>L: "available -= 1"
    else all slots taken
        L->>L: append continuation to waiters (FIFO)
        L->>L: earlier probe calls release()
        L->>L: waiters.removeFirst().resume()
    end
    L->>GMS: await workspaceMetadata(for:)
    GMS-->>L: WorkspaceMetadata
    L-->>TM: InitialWorkspaceGitMetadataSnapshot
    L->>L: defer release()
Loading

Reviews (2): Last reviewed commit: "Cap concurrent git-metadata index parses..." | Re-trigger Greptile

Comment on lines +48 to +56
private func acquire() async {
if available > 0 {
available -= 1
return
}
// Resumed by `release()`, which hands off its slot directly without
// bumping `available`, so the slot count stays balanced.
await withCheckedContinuation { waiters.append($0) }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Cancellation hole: queued probes run after their task is cancelled

withCheckedContinuation does not respond to Swift cooperative cancellation — a task whose Task.isCancelled flag is set while it is waiting in waiters stays parked until a slot is released and release() resumes it. When finally dequeued, body() runs to completion anyway (including the Data(contentsOf:) read inside workspaceMetadata). In a burst where several workspaces close while ~36 probes are queued, cancelled probes still absorb a slot, perform unnecessary disk I/O, and delay the legitimate probes behind them.

The fix is to wrap the suspension in withTaskCancellationHandler, removing the cancelled continuation from waiters and releasing the slot without running body().

Comment on lines +20 to +33
public actor GitProbeConcurrencyLimiter {
private let maxConcurrent: Int
private var available: Int
private var waiters: [CheckedContinuation<Void, Never>] = []

/// Creates a limiter allowing at most `maxConcurrent` probes to run at once.
///
/// - Parameter maxConcurrent: The concurrency ceiling. Values below 1 are
/// clamped to 1 so the limiter always makes forward progress.
public init(maxConcurrent: Int) {
let ceiling = max(1, maxConcurrent)
self.maxConcurrent = ceiling
self.available = ceiling
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 maxConcurrent is stored as an instance property but is never read after init. The live ceiling is tracked entirely by available; maxConcurrent is dead state. It can be removed.

Suggested change
public actor GitProbeConcurrencyLimiter {
private let maxConcurrent: Int
private var available: Int
private var waiters: [CheckedContinuation<Void, Never>] = []
/// Creates a limiter allowing at most `maxConcurrent` probes to run at once.
///
/// - Parameter maxConcurrent: The concurrency ceiling. Values below 1 are
/// clamped to 1 so the limiter always makes forward progress.
public init(maxConcurrent: Int) {
let ceiling = max(1, maxConcurrent)
self.maxConcurrent = ceiling
self.available = ceiling
}
public actor GitProbeConcurrencyLimiter {
private var available: Int
private var waiters: [CheckedContinuation<Void, Never>] = []
/// Creates a limiter allowing at most `maxConcurrent` probes to run at once.
///
/// - Parameter maxConcurrent: The concurrency ceiling. Values below 1 are
/// clamped to 1 so the limiter always makes forward progress.
public init(maxConcurrent: Int) {
self.available = max(1, maxConcurrent)
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 4, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift`:
- Around line 48-56: Update acquire() to support task cancellation by wrapping
the withCheckedContinuation wait in a withTaskCancellationHandler so cancelled
tasks are removed from the waiters queue; specifically, when calling
withCheckedContinuation in GitProbeConcurrencyLimiter.acquire(), register the
continuation object in waiters, and in the onCancel handler remove that specific
continuation (ensure removal and append are atomic relative to release()) so
cancelled continuations don't linger, and adjust release() if necessary to
handle the case where a continuation was removed. Use the existing symbols
acquire(), waiters, and release() to locate where to add the cancellation
handler and removal logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 00f38ac4-3485-41bc-a293-4e76daa31379

📥 Commits

Reviewing files that changed from the base of the PR and between 5b6325d and e1677a7.

📒 Files selected for processing (5)
  • Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift
  • Packages/CmuxGit/Sources/CmuxGit/Parsing/GitMetadataService+Index.swift
  • Packages/CmuxGit/Tests/CmuxGitTests/GitProbeConcurrencyLimiterTests.swift
  • Packages/CmuxGit/Tests/CmuxGitTests/HexEncodingTests.swift
  • Sources/TabManager.swift

Comment on lines +48 to +56
private func acquire() async {
if available > 0 {
available -= 1
return
}
// Resumed by `release()`, which hands off its slot directly without
// bumping `available`, so the slot count stays balanced.
await withCheckedContinuation { waiters.append($0) }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Optional enhancement: task cancellation support.

Cancelled tasks currently remain in the waiters queue until their slot is granted, potentially delaying other waiters. Consider adding withTaskCancellationHandler around the continuation to remove cancelled waiters from the queue:

await withTaskCancellationHandler {
    await withCheckedContinuation { waiters.append($0) }
} onCancel: {
    Task { await removeCancelledWaiter() }
}

However, this adds complexity (tracking which continuation to remove, ensuring atomicity). The current simple design is acceptable given that git probe work is lightweight and short-lived.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift` around
lines 48 - 56, Update acquire() to support task cancellation by wrapping the
withCheckedContinuation wait in a withTaskCancellationHandler so cancelled tasks
are removed from the waiters queue; specifically, when calling
withCheckedContinuation in GitProbeConcurrencyLimiter.acquire(), register the
continuation object in waiters, and in the onCancel handler remove that specific
continuation (ensure removal and append are atomic relative to release()) so
cancelled continuations don't linger, and adjust release() if necessary to
handle the case where a continuation was removed. Use the existing symbols
acquire(), waiters, and release() to locate where to add the cancellation
handler and removal logic.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 5 files

You’re at about 98% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift">

<violation number="1" location="Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift:55">
P1: Handle cancellation while waiting in `acquire()`: a cancelled task currently stays queued until resumed and then still runs `body()`, which wastes a slot and can perform unnecessary git probe I/O.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

}
// Resumed by `release()`, which hands off its slot directly without
// bumping `available`, so the slot count stays balanced.
await withCheckedContinuation { waiters.append($0) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Handle cancellation while waiting in acquire(): a cancelled task currently stays queued until resumed and then still runs body(), which wastes a slot and can perform unnecessary git probe I/O.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Packages/CmuxGit/Sources/CmuxGit/GitProbeConcurrencyLimiter.swift, line 55:

<comment>Handle cancellation while waiting in `acquire()`: a cancelled task currently stays queued until resumed and then still runs `body()`, which wastes a slot and can perform unnecessary git probe I/O.</comment>

<file context>
@@ -0,0 +1,65 @@
+        }
+        // Resumed by `release()`, which hands off its slot directly without
+        // bumping `available`, so the slot count stays balanced.
+        await withCheckedContinuation { waiters.append($0) }
+    }
+
</file context>

@austinywang

Copy link
Copy Markdown
Contributor Author

Superseded by #5402, which already implements the same two fixes for #4639 (table-based hex encoder replacing the String(format: "%02x") locale-lock hot loop, and a bounded concurrency limiter on the git-metadata probes) plus snapshot batching and coalescing. Closing this as redundant. The exhaustive all-256-byte hex equivalence test here may be worth porting, and #5402's limiter could be injected rather than a static let shared singleton.

@austinywang austinywang closed this Jun 5, 2026
@austinywang austinywang reopened this Jun 5, 2026
@lawrencecchen
lawrencecchen dismissed coderabbitai[bot]’s stale review June 6, 2026 11:34

CodeRabbit now posts non-blocking comment reviews (request_changes_workflow=false, #5538).

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — e1677a71 Deployed Jun 4, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants