Created
January 27, 2023 17:35
-
-
Save joshuajhomann/83d35ab381721ee47dfa2d0440756484 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
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