Skip to content

Instantly share code, notes, and snippets.

@omochi
Created May 22, 2024 23:55
Show Gist options
  • Save omochi/52b2ea4278571e633c20a9bdb96fca71 to your computer and use it in GitHub Desktop.
Save omochi/52b2ea4278571e633c20a9bdb96fca71 to your computer and use it in GitHub Desktop.
struct TimeoutError: Error {}
// 記事のコードそのまま
func runWithTimeout<T>(
timeout: Duration,
_ operation: @Sendable () async throws -> T
) async throws -> T {
return try await withoutActuallyEscaping(operation) { operation in
return try await withThrowingTaskGroup(of: T?.self) { g in
g.addTask(operation: operation)
g.addTask {
try await Task.sleep(for: timeout)
return nil
}
if let result = try await g.next(), let result {
return result
}
throw TimeoutError() // タイムアウトした際のエラー
}
}
}
func myAsyncProc() async {
// continuationで実装する自由な処理
await withCheckedContinuation { (c) in
// 中身は5秒かかる非同期処理を模した無意味な例
Task {
try await Task.sleep(for: .seconds(5))
c.resume()
}
}
}
func main() async throws {
// 自由な処理に、タイムアウトを設定して呼び出す
do {
try await runWithTimeout(timeout: .seconds(1)) {
await myAsyncProc()
}
print("proc completed")
} catch {
if error is TimeoutError {
// 5秒後にこれが呼ばれるという期待していない挙動となる
print("timeout")
} else {
fatalError("error: \(error)")
}
}
}
try await main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment