Last active
November 7, 2024 06:43
-
-
Save swhitty/9be89dfe97dbb55c6ef0f916273bbb97 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Task where Failure == Error { | |
// Start a new Task with a timeout. If the timeout expires before the operation is | |
// completed then the task is cancelled and an error is thrown. | |
init(priority: TaskPriority? = nil, timeout: TimeInterval, operation: @escaping @Sendable () async throws -> Success) { | |
self = Task(priority: priority) { | |
try await withThrowingTaskGroup(of: Success.self) { group -> Success in | |
group.addTask(operation: operation) | |
group.addTask { | |
try await _Concurrency.Task.sleep(nanoseconds: UInt64(timeout * 1_000_000_000)) | |
throw TimeoutError() | |
} | |
guard let success = try await group.next() else { | |
throw _Concurrency.CancellationError() | |
} | |
group.cancelAll() | |
return success | |
} | |
} | |
} | |
} | |
private struct TimeoutError: LocalizedError { | |
var errorDescription: String? = "Task timed out before completion" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A Swift 6 compatible version is available within the micro package swhitty/swift-timeout