The user clicks stop. The text stops arriving. That is the visible part of cancellation, and it is easy to mistake it for the whole operation.
A worker may still be executing. A provider request may still be active. A subscription may remain registered. A result may arrive later and overwrite the state of a newer attempt. The interface can look calm while the system keeps spending resources.
Define what stops
I would define cancellation separately for each layer: browser delivery, job execution, provider work, and persistence. Some layers may support immediate interruption; others may only stop at a safe checkpoint. The product should represent those limits accurately.
For an illustrative document workflow, a cancellation request during extraction could mean “finish the current file, then do not start another.” For a live response, it might mean “close delivery and attempt to stop generation.” Those are different promises.
The system should distinguish cancellation requested from cancellation confirmed when confirmation is not immediate.
Protect the next attempt
A common race appears when a user cancels one request and starts another. The old result arrives late. If the interface identifies work only by the current loading flag, the obsolete result can be displayed as if it belongs to the new request.
A stable job identity and an explicit current-attempt check make that boundary visible. The browser accepts updates for the attempt it is observing. The server records each attempt separately. “Latest response wins” is a fragile substitute for ownership.
This matters even when cancellation cannot halt a remote operation. The application can still refuse to attach stale output to the wrong workflow.
Review the cleanup
Cancellation should release listeners, timers, buffers, and temporary state. Cleanup needs to be safe when called more than once, because completion and cancellation can race.
The same review should ask what happens to partial artifacts. Are they retained for recovery, deleted, or marked incomplete? A document that looks finished but was interrupted halfway through is an avoidable source of confusion.
I think of cancellation as a small distributed protocol. The user expresses intent; components acknowledge it according to their capabilities; the interface shows the resulting state. A trustworthy stop button makes that protocol understandable instead of merely making the screen quiet.