Skip to content

Instantly share code, notes, and snippets.

@swhitty
Last active April 11, 2025 05:23
Show Gist options
  • Save swhitty/9be89dfe97dbb55c6ef0f916273bbb97 to your computer and use it in GitHub Desktop.
Save swhitty/9be89dfe97dbb55c6ef0f916273bbb97 to your computer and use it in GitHub Desktop.
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"
}
@akaraatanasov
Copy link

Apple documentation is shit as usual. Thank you @swhitty & @MrDzmitry for the great discussion! It was a great learning resource for me on async/await.

@swhitty
Copy link
Author

swhitty commented Sep 1, 2024

A Swift 6 compatible version is available within the micro package swhitty/swift-timeout

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment