skip to content

When the component that started a request is destroyed before the response arrives, should that request be cancelled?

level: seniorimportance: should knowfreq 55%

answer

  1. two questions, not one
  2. where it may write versus whether to stop
  3. ownership decides who cancels
  4. count consumers before aborting
  5. a sent write is never cancelled for convenience

basics

~10 s

It depends who owns the request. A read whose only consumer was that instance should be cancelled; a read a shared layer keeps for other consumers should finish. A write already sent must complete.

solid answer

~50 s

Separate two obligations. First, nothing may write into an instance that no longer exists — which a per-request identity check or the layer's own bookkeeping handles regardless of cancellation. Second, decide whether the network work should stop, and that is an ownership question. Cancel when the result was private to the destroyed instance and costs something real: a large payload, a scarce connection, an expensive server query. Let it finish when a shared layer will store the answer for the next consumer, when other consumers are attached to the same request, or when a rapid destroy-and-recreate pattern would otherwise cancel and restart the same work repeatedly. A write that has already gone to the server is never cancelled merely because its trigger disappeared, since cancelling the client side tells you nothing about whether the server applied it.

go deeper

for a junior

Know that a response can arrive after its requester is gone, and that the response must not be written anywhere at that point.

for a middle

Separate the two obligations cleanly: blocking the write is correctness, stopping the network work is a cost decision, and cancellation is not a failure.

for a senior

Reason from ownership: private and expensive reads get cancelled, shared or nearly-finished ones finish, sent writes always finish, and consumer counts gate cancellation of shared work.

for a principal

Set the policy and its defaults — what the layer cancels automatically, how write outcomes survive the screen that triggered them, and how cancellations are kept out of error budgets and alerting.

## Two obligations, not one A response that arrives after its requester is gone raises two separate questions, and candidates who merge them give a confused answer. 1. **Where may the response write?** Nowhere, if the instance is gone. This is settled by the same request-identity bookkeeping that resolves out-of-order responses, or by a shared layer that owns the destination rather than the instance. It requires no cancellation at all. 2. **Should the work stop?** That is a cost decision about the network and the server, and it turns on **who owns the request**. Treating question two as if it were question one produces the blanket rule "cancel everything on teardown", which is wrong often enough to matter. ## When cancelling is the right answer - The result was **private to the destroyed instance** — a detail panel's payload nobody else reads. - The payload is **large or expensive**: a heavy list, a report, an export, a query whose server cost is worth reclaiming. - Connections are **scarce** and the screen being torn down held several. - The request was already **superseded** by a newer one for the same slot, in which case cancelling was due anyway. - The user's intent is unmistakable: they navigated away from the thing the data was for. ## When letting it finish is the right answer - A **shared store will keep the answer**, so the work benefits whoever asks next instead of being thrown away. - **Other consumers are attached** to the same in-flight request; cancelling because one left breaks the rest. - The instance is being **destroyed and recreated rapidly** — a list that recycles rows, a route the user flicks between — where cancel-and-restart turns one request into many and makes the screen slower than doing nothing. - The request is nearly done; aborting buys nothing and loses an answer already paid for. - The response has a **side benefit**, such as populating a shared store or warming an intermediate cache. ## Writes are a separate category An in-flight write must not be cancelled just because the surface that triggered it disappeared. Cancelling is a client-side detachment: the server may already have applied the change, and the client has simply thrown away its only evidence of the outcome. The consequences are real — a change the user believes failed but which took effect, or a retry that applies it twice. If a write must survive the screen that started it, it belongs to something with a longer life than that screen, and its outcome needs a destination — a shared store, a notification surface — that still exists when the answer lands. ## Ownership decides | | Owned by the instance | Owned by a shared layer | |---|---|---| | Who may cancel | the instance, on teardown | the layer, when the last consumer detaches | | Rapid destroy and recreate | cancel then restart, repeatedly | one request continues, and the new instance joins it | | Where the response goes | nowhere once the owner is gone | into the store, for whoever asks next | | Failure mode to watch | work thrown away and redone | a request kept alive that nobody will ever read | | Fit | one-off, screen-private reads | data several screens read | This is why the answer to the interview question is "it depends, and here is what it depends on". A blanket policy in either direction produces a predictable class of bug: cancel everything and you get thrash plus lost writes; cancel nothing and you get work running for nobody, held connections, and a slow screen under fast navigation. ## Traps worth naming - **Rendering the cancellation as a failure.** A teardown cancellation reaching an error surface produces failure reports during ordinary navigation. - **Assuming cancellation stops the server.** It detaches the client; the work may already have completed. - **Cancelling a shared request when one of several consumers leaves.** Count consumers first. - **Relying on liveness alone.** A check that only refuses to write into a destroyed instance leaves the request running for nobody, which is a resource decision you have silently made by not making it. - **Retry colliding with teardown.** A retry policy that does not know its consumer is gone will happily keep attempting a request whose result nobody will read; the cancellation must reach the retry loop, not just the current attempt. - **Cancelling on every re-evaluation rather than on genuine teardown.** In a runtime that re-runs the component function on each state write, careless wiring can tear down and restart the request on every pass; a fine-grained or compile-time runtime re-runs less, so the same code races differently. The safe framing is that cancellation belongs to the *lifetime of the request's owner*, not to a render pass.

  • Why is 'cancel every in-flight request on teardown' a dangerous blanket rule?
    Because it treats a cost decision as a correctness rule. It can abort a write the server already applied, discard a read a shared store would have kept for the next consumer, and turn rapid navigation into a cancel-and-restart storm. Blocking the write into a destroyed instance is what correctness needs; whether to stop the work is a separate judgement.
  • A user navigates away while a write is in flight. What should happen to the outcome?
    The write continues, and its outcome needs a destination that outlives the screen: a shared store the next screen reads, plus a surface that can report failure out of band. Otherwise the user is left with a change of unknown status — possibly applied, possibly not — and no way for the application to reconcile it.
  • Two consumers share one in-flight read and one of them is destroyed. What should the layer do?
    Decrement the count of attached consumers and keep the request running, because one consumer still needs the answer. Cancellation only becomes a candidate when the count reaches zero, and even then the layer may prefer to finish and store the result rather than throw away work that is nearly done.
  • How do you keep teardown cancellations out of error reporting?
    Classify the outcome at the boundary: a cancellation you initiated is not a failure, so it never reaches the error state, the retry policy, or the log stream as an incident. That distinction has to be explicit, because the alternative is error rates and user-visible banners that track navigation speed rather than anything wrong with the system.

saying these in an interview costs you the question

  • Cancels every in-flight request on teardown, including a write already sent
  • Believes the server stops working the moment the client cancels
  • Shows a teardown cancellation to the user as a failed request
  • Relies only on a liveness check, leaving the request running for nobody
  • Cancels a shared request as soon as its first consumer disappears
  • Cancels and restarts the same read on every rapid remount of the same screen