Skip to content

Instantly share code, notes, and snippets.

@eczn
Last active July 17, 2023 04:29
Show Gist options
  • Save eczn/7da07d3deef86065eaa614af7c534cc4 to your computer and use it in GitHub Desktop.
Save eczn/7da07d3deef86065eaa614af7c534cc4 to your computer and use it in GitHub Desktop.
withTimeoutContinuation.swift
import Foundation
fileprivate var counter = 0
func withTimeoutUnsafeContinuation<T>(
_ labelName: String = "NoName",
_ timeout: TimeInterval = 2.0,
_ fn: @escaping (UnsafeContinuation<T?, Never>) -> Void
) async -> T? {
let nth = counter + 1
counter = counter + 1
let task = Task<T?, Never> {
return await withUnsafeContinuation { continuation in
fn(continuation)
}
}
let sleep = Task {
try await Task.sleep(for: .seconds(timeout))
task.cancel()
}
let result = await task.value
sleep.cancel()
if task.isCancelled {
print("[TASK][\(nth)][\(labelName)]", "Timeout canceled, return nil")
return nil
}
print("[TASK][\(nth)][\(labelName)]", "task done")
return result
}
let timeout = 2.0
let outter = Task {
print("start")
let r = try? await withTimeoutUnsafeContinuation("XX", timeout) { continuation in
print("AAA")
let start = Date.now
while abs(start.timeIntervalSinceNow) < 3.0 { }
print("BBB")
continuation.resume(returning: 999999)
}
print("ends", r)
}
RunLoop.current.run(mode: RunLoop.Mode.default, before: Date.now.addingTimeInterval(5.0))
// all output is:
// start
// AAA
// BBB
// [TASK][1][XX] Timeout canceled, return nil
// ends nil
// if let timeout = 4.0, all output is
// start
// AAA
// BBB
// [TASK][1][XX] task done
// ends Optional(999999)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment