Skip to content

Instantly share code, notes, and snippets.

@jayrhynas
Last active December 10, 2024 15:15
Show Gist options
  • Save jayrhynas/16b7eaa721dd58d709cf6e9bcec5ba03 to your computer and use it in GitHub Desktop.
Save jayrhynas/16b7eaa721dd58d709cf6e9bcec5ba03 to your computer and use it in GitHub Desktop.
func forceCancellable<R>(isolation: isolated (any Actor)? = #isolation, _ body: @escaping () async throws -> R) async throws -> R {
let (stream, continuation) = AsyncThrowingStream.makeStream(
of: R.self,
throwing: Error.self,
bufferingPolicy: .bufferingOldest(1)
)
let task = Task {
do {
let result = try await body()
continuation.yield(result)
} catch {
continuation.yield(with: .failure(error))
}
}
return try await withTaskCancellationHandler(operation: {
for try await value in stream {
return value
}
throw CancellationError()
}, onCancel: {
task.cancel()
}, isolation: isolation)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment