fix(macos): enforce node bridge timeouts

This commit is contained in:
Peter Steinberger
2025-12-27 00:02:41 +01:00
parent d0293649cd
commit 4daf75a469
3 changed files with 33 additions and 27 deletions

View File

@@ -177,18 +177,20 @@ actor MacNodeBridgePairingClient {
purpose: String,
operation: @escaping @Sendable () async throws -> T) async throws -> T
{
let task = Task { try await operation() }
let timeout = Task {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
try await withThrowingTaskGroup(of: T.self) { group in
group.addTask { try await operation() }
group.addTask {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
throw NSError(domain: "Bridge", code: 0, userInfo: [
NSLocalizedDescriptionKey: "\(purpose) timed out",
])
}
let result = try await group.next()
group.cancelAll()
if let result { return result }
throw NSError(domain: "Bridge", code: 0, userInfo: [
NSLocalizedDescriptionKey: "\(purpose) timed out",
])
}
defer { timeout.cancel() }
return try await withTaskCancellationHandler(operation: {
try await task.value
}, onCancel: {
timeout.cancel()
})
}
}

View File

@@ -315,16 +315,18 @@ actor MacNodeBridgeSession {
seconds: Double,
operation: @escaping @Sendable () async throws -> T) async throws -> T
{
let task = Task { try await operation() }
let timeout = Task {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
try await withThrowingTaskGroup(of: T.self) { group in
group.addTask {
try await operation()
}
group.addTask {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
throw TimeoutError(message: "operation timed out")
}
let result = try await group.next()
group.cancelAll()
if let result { return result }
throw TimeoutError(message: "operation timed out")
}
defer { timeout.cancel() }
return try await withTaskCancellationHandler(operation: {
try await task.value
}, onCancel: {
timeout.cancel()
})
}
}

View File

@@ -253,19 +253,21 @@ final class MacNodeModeCoordinator {
seconds: Double,
operation: @escaping @Sendable () async throws -> T) async throws -> T
{
let task = Task { try await operation() }
let timeout = Task {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
try await withThrowingTaskGroup(of: T.self) { group in
group.addTask { try await operation() }
group.addTask {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
throw NSError(domain: "Bridge", code: 22, userInfo: [
NSLocalizedDescriptionKey: "operation timed out",
])
}
let result = try await group.next()
group.cancelAll()
if let result { return result }
throw NSError(domain: "Bridge", code: 22, userInfo: [
NSLocalizedDescriptionKey: "operation timed out",
])
}
defer { timeout.cancel() }
return try await withTaskCancellationHandler(operation: {
try await task.value
}, onCancel: {
timeout.cancel()
})
}
private func resolveBridgeEndpoint(timeoutSeconds: Double) async -> NWEndpoint? {