Created
May 22, 2024 23:55
-
-
Save omochi/52b2ea4278571e633c20a9bdb96fca71 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 {} | |
// 記事のコードそのまま | |
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