apple / apple/swift-async-algorithms
Calling debounce is causing async stream to get cancelled early
- Dominant language
- Swift
- Stars
- 3.7k
- Forks
- 226
- Avg merge
- 10d 3h
- Merged PRs (30d)
- 1
Description
I made a post about this [here](https://forums.swift.org/t/calling-debounce-is-causing-async-stream-to-get-cancelled-early/86158/1).
I was recently testing out the debounce method and I noticed some strange behavior that I didn't expect. It looks the async stream I have set up is getting cancelled early when I'm calling the debounce method but it doesn't do that without the debounce method. This seems like a bug but I'm curious to hear others thoughts on it.
Here is the reproducer I have. Thanks!
```swift
@Test
func debounceCancellation() async {
enum Status {
case inProgress
case completed
}
let drawStatues = AsyncStream { continuation in
Task {
continuation.yield(.inProgress)
try! await Task.sleep(for: .seconds(2))
continuation.yield(.completed)
}
continuation.onTermination = { termination in
switch termination {
case .cancelled:
print("Cancelled!")
case .finished:
print("Finished!")
@unknown default:
fatalError("Unknown case")
}
}
}
_ = await drawStatues
.debounce(for: .seconds(2))
.first(where: { @Sendable in $0 == .completed })
// Current behavior when using debounce:
// cancelled -> end
//
// Expected behavior without using debounce:
// end -> cancelled
print("End")
}
```
Contributor guide
Research direction
Start by running the issue's Swift reproducer with and without debounce, comparing the AsyncStream termination order. Read the debounce and first(where:) behavior involved in the example; done means the stream is not cancelled before the completed value is observed and the expected termination ordering is preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100