Skip to content

Instantly share code, notes, and snippets.

@joshuajhomann
Created January 27, 2023 17:35
Show Gist options
  • Save joshuajhomann/83d35ab381721ee47dfa2d0440756484 to your computer and use it in GitHub Desktop.
Save joshuajhomann/83d35ab381721ee47dfa2d0440756484 to your computer and use it in GitHub Desktop.
struct TimeOutError: Error { }
extension Result where Failure == Error {
init(awaiting operation: () async throws -> Success) async {
do {
self = .success(try await operation())
} catch {
self = .failure(error)
}
}
}
func timeout<Value: Sendable>(
after milliseconds: Int,
operation: @escaping () async throws -> Value
) async throws -> Value {
let result = await withTaskGroup(of: Result<Value, Error>.self) { group in
group.addTask { await Result { try await operation() } }
group.addTask {
try? await Task.sleep(until: .now + .milliseconds(milliseconds), clock: .continuous)
return .failure(TimeOutError())
}
defer { group.cancelAll() }
return await group.first(where: { _ in true })!
}
return try result.get()
}
Task { @MainActor in
async let first = await Result {
try await timeout(after: 1000) {
try await Task.sleep(until: .now + .seconds(2), clock: .continuous)
return 1
}
}
async let second = await Result {
try await timeout(after: 1000) {
try await Task.sleep(until: .now + .milliseconds(250), clock: .continuous)
return 2
}
}
print(await first, await second)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment