Skip to content

Decouple AbortSignal from IOContext#6273

Draft
jasnell wants to merge 1 commit intomainfrom
jasnell/decouple-abortsignal-from-iocontext
Draft

Decouple AbortSignal from IOContext#6273
jasnell wants to merge 1 commit intomainfrom
jasnell/decouple-abortsignal-from-iocontext

Conversation

@jasnell
Copy link
Collaborator

@jasnell jasnell commented Mar 7, 2026

Allow a AbortController/AbortSignal to be created outside of a request context, and allow cross-context aborts to work.

In some ways this is a bit of a hack. When a native abort handler is added from one IoContext, and the abort is triggered from another IoContext, the, we have to arrange for the handler to trigger the actual kj::Canceler from the right IoContext. We do this using the same approach we use for cross-context promises: we abuse...er, use.. the DeleteQueue to schedule the canceler to trigger the next time the correct IoContext is entered.

This needs to be reviewed very carefully!

I'm not likely to land this as is, I'll probably restore the original impl and add an autogate to switch between two different AbortSignal impls but I want to get an initial review on the approach before making those changes.

@jasnell jasnell requested review from a team as code owners March 7, 2026 00:38
Copy link
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm Bonk, and I've done a quick review of your PR.

This decouples AbortSignal from IoContext by removing the per-signal IoOwn<RefcountedCanceler> member and creating per-use cancelers via newMaybeCrossContextCancelHandler. Findings ranked by severity:

  1. [HIGH] Missing subscribeToRpcAbort call in newMaybeCrossContextCancelHandler — RPC-deserialized signals won't fire the canceler
  2. [HIGH] Missing already-aborted check in maybeCancelWrapscheduler.wait with an already-aborted signal silently hangs instead of throwing
  3. [MED] Fragile exception description string matching in handleCancelablePump
  4. [LOW] Stale visitForMemoryInfo at basics.h:702-707 still tracks IoOwn<RefcountedCanceler> as an inline field, but the canceler member was removed. Should remove the trackInlineFieldWithSize line.
  5. [LOW] Typo: "non-op" should be "no-op"

This review was generated by an AI assistant and may contain inaccuracies. Please verify all suggestions before applying.

@ask-bonk
Copy link
Contributor

ask-bonk bot commented Mar 7, 2026

Review posted successfully. Here's a summary of the findings on PR #6273:

  1. [HIGH] Missing subscribeToRpcAbort call -- The old wrap() called subscribeToRpcAbort(js) to set up RPC abort listening. The new newMaybeCrossContextCancelHandler doesn't, so RPC-deserialized signals used in maybeCancelWrap won't trigger the canceler when the remote side aborts.

  2. [HIGH] Missing already-aborted check -- The old wrap() threw a synchronous TypeError for already-aborted signals. The new maybeCancelWrap creates a fresh canceler that will never fire, causing scheduler.wait with an already-aborted signal to silently hang.

  3. [MED] Fragile string matching -- exception.getDescription().startsWith("jsg.DOMException(AbortError): ") in http.c++ depends on internal tunneling format details.

  4. [LOW] Stale visitForMemoryInfo -- Still tracks the removed IoOwn<RefcountedCanceler> field.

  5. [LOW] Typo -- "non-op" should be "no-op".

github run

ask-bonk bot added a commit that referenced this pull request Mar 7, 2026
Co-authored-by: jasnell <jasnell@users.noreply.github.com>
@ask-bonk ask-bonk bot requested a review from a team as a code owner March 7, 2026 00:45
@jasnell jasnell force-pushed the jasnell/decouple-abortsignal-from-iocontext branch 3 times, most recently from 9cda17d to ffef7fe Compare March 7, 2026 01:10
Allow a AbortController/AbortSignal to be created outside
of a request context, and allow cross-context aborts to work.

In some ways this is a bit of a hack. When a native abort
handler is added from one IoContext, and the abort is triggered
from another IoContext, the, we have to arrange for the handler
to trigger the actual kj::Canceler from the right IoContext.
We do this using the same approach we use for cross-context
promises: we abuse...er, use.. the DeleteQueue to schedule the
canceler to trigger the next time the correct IoContext is entered.
@jasnell jasnell force-pushed the jasnell/decouple-abortsignal-from-iocontext branch from ffef7fe to 66a9daa Compare March 7, 2026 01:48
@jasnell jasnell marked this pull request as draft March 7, 2026 04:15
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