Skip to content

Instantly share code, notes, and snippets.

@swhitty
Last active November 7, 2024 06:43
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"
}
@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