Description
Goals
- Introduce a cancellable interface to the existing FIFOQueue implementation.
Technical Details
- Tasks can be cancelled before they start, and the cancellation will be propagated correctly.
- Task cancellation is handled using
withTaskCancellationHandler
to ensure proper cleanup.
API Overview
public func enqueue<T: Sendable>(
_ task: @escaping @Sendable () async throws -> T
) async throws -> T
Example Usage
let queue = FIFOQueue()
let task = Task {
do {
let result = try await queue.enqueueWithCancellation {
try Task.sleep(seconds: 1)
}
print("Task completed with result: \(result)")
} catch {
print("Task was cancelled or failed with error: \(error)")
}
}
task.cancel()
I have developed a similar queue functionality that has a cancellable enqueue
method implementation. This allowed tasks to be enqueued with the ability to cancel them if needed either when they already started or when they are waiting in the queue. I believe this feature could be a valuable addition to your library. Would you be interested in me opening a pull request with this functionality?
Update:
I discovered that while implementing cancellation is possible, it loses the ability to propagate Task locals to the enqueued tasks. Extra work is required to hold a handle on a task to cancel it without starting it immediately and this involves starting a task from the escaped boundary, which means it doesn't retain locals of the tasks that enqueued the task. I believe this behavior would be unexpected and confusing with the proposed interface moving forward.