Skip to content

Cancel the orphaned progressive operation when a dependency fails - #898

Merged
kean merged 2 commits into
mainfrom
fix/async-task-cancel-operation-on-error
Aug 15, 2026
Merged

kean merged 2 commits into
mainfrom
fix/async-task-cancel-operation-on-error

Conversation

@kean

@kean kean commented Aug 15, 2026 •

Copy link
Copy Markdown
Owner

A pending progressive decode, processing, or decompression operation is cancelled when the final value arrives — TaskFetchOriginalImage.didReceiveData, TaskLoadImage.process, and TaskLoadImage.didReceiveImageResponse all do it explicitly. The errors bypass those call sites entirely: they are forwarded generically by AsyncTask.Publisher.subscribe(_:onValue:), so a task that failed left its operation in the queue, holding on to the decoded preview and the captured decoder until the queue drained past it.

The cancellation now happens in that forwarder. It deliberately isn't in AsyncTask.terminate: operation is either the work a task awaits (decoding, processing — cleared before the result is delivered) or the operation that runs the task itself (TaskFetchOriginalData.loadData, loadAsyncData, TaskFetchOriginalImage.loadAsyncImage — never cleared). For the latter, the terminal event is reported from inside the operation, and since send terminates before delivering the event, a blanket cancel would run the whole downstream delivery chain inside a just-cancelled Task.

TaskLoadImage.didReceiveImageResponse also checks isDisposed before the no-decompression early return, so a late response can't reach storeImageInCaches and write a stale preview to the memory cache after the task has ended.

kean added 2 commits August 15, 2026 12:43
Without the guard, a response that doesn't need decompression still reached
`storeImageInCaches`, letting a stale progressive result write to the memory
cache after the task had already ended.
A pending progressive decode/process/decompress is cancelled when the final
value arrives, but the errors bypass those call sites: they are forwarded
generically, so the operation was left in the queue holding on to the decoded
preview until the queue drained past it.
@kean
kean force-pushed the fix/async-task-cancel-operation-on-error branch from 96d7dbe to 2591f4b Compare August 15, 2026 16:44
@kean kean changed the title Cancel the outstanding queue operation when a task terminates with an error Cancel the orphaned progressive operation when a dependency fails Aug 15, 2026
@kean
kean merged commit 0fb3c57 into main Aug 15, 2026
5 checks passed
@kean
kean deleted the fix/async-task-cancel-operation-on-error branch August 16, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant