Yes, we agree that AsyncStream
handles the cancellation in the sense of the Task
Swift cancellation.
But it does not allow us to handle fully the cooperative cancelation in the sense that we discuss here.
Maybe for the most common use cases, current behavior is fine.
Still, I'm not at all convinced that there is no need to allow handling the cancellation in the producer side of the stream in case of cancellation to give the developer full control over the behavior.
Even by changing the example code by removing the Task.sleep
, it makes perfect sense.
let (stream, source) = MyCustomAsyncStream<Int, Never>.makeStream()
rootAsyncSequence.onConsumerCancellation = {
// When the consumer gets cancelled we want to send two more elements and then finish
source.send(1)
source.send(2)
source.finish()
}
let task = Task {
for await element in stream {
print(element)
// REMOVE Task.sleep
}
}
// Cancelling the task after 1.5 seconds
try await Task.sleep(for: .seconds(1.5))
task.cancel()
There is no end of examples that could benefit from having full control over the cancellation (mine).
I would say the opposite.
Cooperative cancellation in my opinion was a great design choice by not treating API users as “not have to think about cancellation”. Rather have to think about the cancellation.
I think this topic was created, and others exactly because of "we think about cancellation" but AsyncStream
does not allow to fully control that.
I would disagree. Why not use the Swift concurrency model for asynchronous work that requires action on Task
cancellation?
Then I don't see much sense why cooperative cancellation would be introduced anyway.