Skip to content

Cancel misses a batch mid-promotion, letting a cancelled request reach speculation #825

Open

Description

@behinddwalls

Problem

A request cancelled in the window between dependency analysis claiming it (validated → batched) and promoting its batch out of creating reaches speculation anyway. The result is a live batch carrying a request the user cancelled; it will build, and it can merge.

Interleaving

dependency analysis:  request validated → batched     (claimRequestsForBatch)
cancel:               request batched → cancelling    (markCancelling)
cancel:               findBatches sees only a creating batch — not cancellable
cancel:               request cancelling → cancelled  (no applicable batch → cancelRequest)
dependency analysis:  batch creating → created        (batch-only compare-and-swap)
dependency analysis:  publish to speculate

Why the existing guards miss it

  • The halted-request check in dependency analysis runs before the claim.
  • The claim's re-read and version check reject a cancel that lands before or during the claim, but this window opens after the claim succeeds.
  • creating is not cancellable, so cancel's batch loop matches nothing and falls through to cancelRequest.
  • Neither speculate's admission of created batches nor conclude checks for halted requests.

Found in review of #590. As of 6c050082 the code paths above are unchanged.

Constraint

From #817: a batch abandoned in creating must stay unreachable, and created must remain dependency-eligible.

Activity

  1. burgulvedant commented on Oct 31, 2026

    @burgulvedant

    @behinddwalls I would like to work on this. Before I write code, which direction do you prefer?

    1. Cancel treats a creating batch as in scope when the request was batched when cancel read it, since the claim is the only writer of batched. That batch is then cancelled instead of falling through to cancelRequest.
    2. Speculate admission, and conclude, skip or cancel a batch that contains a halted request. A created batch then cannot build for a cancelled request, whatever the interleaving.
    3. Dependency analysis reads the requests again after the claim and before publishing to speculate. This narrows the window but does not close it, so I would only do it together with option 2.

    I lean towards option 2. It closes the gap where the batch is used and leaves the creating and created rules from #817 untouched. Happy to follow whichever you pick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions