Address PR review feedback
This commit is contained in:
parent
1291776597
commit
0285cd1f51
3 changed files with 51 additions and 12 deletions
|
|
@ -2590,6 +2590,11 @@ struct ContentView: View {
|
|||
case completed(reason: String)
|
||||
}
|
||||
|
||||
private enum BackgroundWorkspacePrimePolicy {
|
||||
static let timeoutSeconds: TimeInterval = 2.0
|
||||
static let pollIntervalNanoseconds: UInt64 = 50_000_000
|
||||
}
|
||||
|
||||
private func primeBackgroundWorkspaceIfNeeded(workspaceId: UUID) async {
|
||||
let shouldPrime = await MainActor.run {
|
||||
tabManager.pendingBackgroundWorkspaceLoadIds.contains(workspaceId)
|
||||
|
|
@ -2601,7 +2606,7 @@ struct ContentView: View {
|
|||
dlog("workspace.backgroundPrime.start workspace=\(workspaceId.uuidString.prefix(5))")
|
||||
#endif
|
||||
|
||||
let timeout = Date().addingTimeInterval(2.0)
|
||||
let timeout = Date().addingTimeInterval(BackgroundWorkspacePrimePolicy.timeoutSeconds)
|
||||
while !Task.isCancelled {
|
||||
let state = await MainActor.run {
|
||||
stepBackgroundWorkspacePrime(workspaceId: workspaceId)
|
||||
|
|
@ -2609,7 +2614,7 @@ struct ContentView: View {
|
|||
switch state {
|
||||
case .pending:
|
||||
if Date() < timeout {
|
||||
try? await Task.sleep(nanoseconds: 50_000_000)
|
||||
try? await Task.sleep(nanoseconds: BackgroundWorkspacePrimePolicy.pollIntervalNanoseconds)
|
||||
continue
|
||||
}
|
||||
await MainActor.run {
|
||||
|
|
|
|||
|
|
@ -635,6 +635,7 @@ class TabManager: ObservableObject {
|
|||
qos: .utility
|
||||
)
|
||||
private var initialWorkspaceGitProbeGenerationByWorkspace: [UUID: UUID] = [:]
|
||||
private var initialWorkspaceGitProbeTimersByWorkspace: [UUID: [DispatchSourceTimer]] = [:]
|
||||
|
||||
// Recent tab history for back/forward navigation (like browser history)
|
||||
private var tabHistory: [UUID] = []
|
||||
|
|
@ -870,6 +871,7 @@ class TabManager: ObservableObject {
|
|||
) {
|
||||
let normalizedDirectory = normalizeDirectory(directory)
|
||||
let generation = UUID()
|
||||
cancelInitialWorkspaceGitProbeTimers(workspaceId: workspaceId)
|
||||
initialWorkspaceGitProbeGenerationByWorkspace[workspaceId] = generation
|
||||
|
||||
#if DEBUG
|
||||
|
|
@ -880,9 +882,12 @@ class TabManager: ObservableObject {
|
|||
#endif
|
||||
|
||||
let delays = Self.initialWorkspaceGitProbeDelays
|
||||
var timers: [DispatchSourceTimer] = []
|
||||
for (index, delay) in delays.enumerated() {
|
||||
let isLastAttempt = index == delays.count - 1
|
||||
initialWorkspaceGitProbeQueue.asyncAfter(deadline: .now() + delay) {
|
||||
let timer = DispatchSource.makeTimerSource(queue: initialWorkspaceGitProbeQueue)
|
||||
timer.schedule(deadline: .now() + delay, repeating: .never)
|
||||
timer.setEventHandler { [weak self] in
|
||||
let snapshot = Self.initialWorkspaceGitMetadataSnapshot(for: normalizedDirectory)
|
||||
Task { @MainActor [weak self] in
|
||||
self?.applyInitialWorkspaceGitMetadataSnapshot(
|
||||
|
|
@ -895,7 +900,25 @@ class TabManager: ObservableObject {
|
|||
)
|
||||
}
|
||||
}
|
||||
timers.append(timer)
|
||||
timer.resume()
|
||||
}
|
||||
initialWorkspaceGitProbeTimersByWorkspace[workspaceId] = timers
|
||||
}
|
||||
|
||||
private func cancelInitialWorkspaceGitProbeTimers(workspaceId: UUID) {
|
||||
guard let timers = initialWorkspaceGitProbeTimersByWorkspace.removeValue(forKey: workspaceId) else {
|
||||
return
|
||||
}
|
||||
for timer in timers {
|
||||
timer.setEventHandler {}
|
||||
timer.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private func clearInitialWorkspaceGitProbe(workspaceId: UUID) {
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: workspaceId)
|
||||
cancelInitialWorkspaceGitProbeTimers(workspaceId: workspaceId)
|
||||
}
|
||||
|
||||
private func applyInitialWorkspaceGitMetadataSnapshot(
|
||||
|
|
@ -909,17 +932,17 @@ class TabManager: ObservableObject {
|
|||
defer {
|
||||
if isLastAttempt,
|
||||
initialWorkspaceGitProbeGenerationByWorkspace[workspaceId] == generation {
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: workspaceId)
|
||||
clearInitialWorkspaceGitProbe(workspaceId: workspaceId)
|
||||
}
|
||||
}
|
||||
|
||||
guard initialWorkspaceGitProbeGenerationByWorkspace[workspaceId] == generation else { return }
|
||||
guard let workspace = tabs.first(where: { $0.id == workspaceId }) else {
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: workspaceId)
|
||||
clearInitialWorkspaceGitProbe(workspaceId: workspaceId)
|
||||
return
|
||||
}
|
||||
guard workspace.panels[panelId] != nil else {
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: workspaceId)
|
||||
clearInitialWorkspaceGitProbe(workspaceId: workspaceId)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -927,7 +950,7 @@ class TabManager: ObservableObject {
|
|||
workspace.panelDirectories[panelId] ?? workspace.currentDirectory
|
||||
)
|
||||
if let currentDirectory, currentDirectory != expectedDirectory {
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: workspaceId)
|
||||
clearInitialWorkspaceGitProbe(workspaceId: workspaceId)
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"workspace.gitProbe.skip workspace=\(workspaceId.uuidString.prefix(5)) " +
|
||||
|
|
@ -980,7 +1003,7 @@ class TabManager: ObservableObject {
|
|||
process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
|
||||
process.arguments = ["git", "-C", directory] + arguments
|
||||
process.standardOutput = stdout
|
||||
process.standardError = Pipe()
|
||||
process.standardError = FileHandle.nullDevice
|
||||
|
||||
do {
|
||||
try process.run()
|
||||
|
|
@ -988,12 +1011,13 @@ class TabManager: ObservableObject {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Drain stdout while the subprocess is active so large repos cannot fill the pipe buffer.
|
||||
let data = stdout.fileHandleForReading.readDataToEndOfFile()
|
||||
process.waitUntilExit()
|
||||
guard process.terminationStatus == 0 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let data = stdout.fileHandleForReading.readDataToEndOfFile()
|
||||
return String(data: data, encoding: .utf8)
|
||||
}
|
||||
|
||||
|
|
@ -1196,7 +1220,7 @@ class TabManager: ObservableObject {
|
|||
guard tabs.count > 1 else { return }
|
||||
guard let index = tabs.firstIndex(where: { $0.id == workspace.id }) else { return }
|
||||
sentryBreadcrumb("workspace.close", data: ["tabCount": tabs.count - 1])
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: workspace.id)
|
||||
clearInitialWorkspaceGitProbe(workspaceId: workspace.id)
|
||||
|
||||
AppDelegate.shared?.notificationStore?.clearNotifications(forTabId: workspace.id)
|
||||
unwireClosedBrowserTracking(for: workspace)
|
||||
|
|
@ -1218,7 +1242,7 @@ class TabManager: ObservableObject {
|
|||
@discardableResult
|
||||
func detachWorkspace(tabId: UUID) -> Workspace? {
|
||||
guard let index = tabs.firstIndex(where: { $0.id == tabId }) else { return nil }
|
||||
initialWorkspaceGitProbeGenerationByWorkspace.removeValue(forKey: tabId)
|
||||
clearInitialWorkspaceGitProbe(workspaceId: tabId)
|
||||
|
||||
let removed = tabs.remove(at: index)
|
||||
unwireClosedBrowserTracking(for: removed)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -16,7 +17,16 @@ sys.path.insert(0, str(Path(__file__).parent))
|
|||
from cmux import cmux, cmuxError
|
||||
|
||||
|
||||
SOCKET_PATH = os.environ.get("CMUX_SOCKET", "/tmp/cmux-debug.sock")
|
||||
def _resolve_socket_path() -> str:
|
||||
socket_path = os.environ.get("CMUX_SOCKET", "").strip()
|
||||
if not socket_path:
|
||||
raise cmuxError("CMUX_SOCKET is required (expected /tmp/cmux-debug-<tag>.sock)")
|
||||
if not re.fullmatch(r"/tmp/cmux-debug-[^/]+\.sock", socket_path):
|
||||
raise cmuxError(f"CMUX_SOCKET must be a tagged debug socket, got: {socket_path!r}")
|
||||
return socket_path
|
||||
|
||||
|
||||
SOCKET_PATH = _resolve_socket_path()
|
||||
|
||||
|
||||
def _must(cond: bool, msg: str) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue