Skip to content

node: allow one pinned actor to use isolate port scope - #7352

Closed
petebacondarwin wants to merge 2 commits into
mainfrom
fix/internal-actor-isolate-node-port-scope
Closed

petebacondarwin wants to merge 2 commits into
mainfrom
fix/internal-actor-isolate-node-port-scope

Conversation

@petebacondarwin

@petebacondarwin petebacondarwin commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

#7306 correctly made Node.js virtual port tables Durable Object instance-scoped. Vite and Vitest, however, evaluate user modules inside pinned synthetic runner actors and later invoke the exported handlers from their real I/O contexts. A Node server registered during module evaluation is therefore currently invisible to httpServerHandler() during dispatch.

This adds an unsafe Durable Object namespace option whose value names the one ephemeral-local actor allowed to use its worker isolate's Node port table. The namespace compares each actor's ID before carrying that scope choice into Worker::Actor, where cloudflare-internal:sockets selects the isolate table.

Configuration is rejected if preventEviction is absent, if the namespace is not ephemeral-local, or if another namespace in the same Worker already names an isolate-scope actor. All other durable and ephemeral-local actors retain their per-instance port tables.

Why this is in workerd

Redirecting handler invocation back through the synthetic runner actor can make a trivial GET pass, but changes the request/response transport boundary and breaks body and streaming semantics. The runner actor is an artificial module-evaluation context, so selecting the intended port-table host at the runtime boundary preserves normal handler dispatch.

Feedback requested

This is a draft to align the runtime and tooling teams before settling the API. In particular:

  • Is an actor-ID-valued namespace escape hatch the right representation for an internal pinned actor?
  • Is unsafeUseIsolateNodePortScopeForActor the right name and level of specificity?
  • Is rejecting a second configured namespace per Worker the right cardinality guard?

Restricting the option to ephemeralLocal also puts it behind workerd's existing --experimental gate.

Paired workers-sdk draft: cloudflare/workers-sdk#15637

Tests

  • New Node HTTP port-scope test covers cross-context dispatch with request and response bodies.
  • The same test lets two IDs bind the same port and proves only the configured ID uses isolate scope.
  • Existing tests confirm ordinary durable and ephemeral-local actors remain isolated.
  • Server tests enforce pinning, ephemeral-local scope, and one configured actor per Worker.

Comment thread src/workerd/server/server.c++ Outdated
@ask-bonk

ask-bonk Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

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

Adds isolate-scoped Node port tables for pinned Durable Objects.

Posted 1 inline high-severity finding.

github run

@petebacondarwin petebacondarwin changed the title node: allow pinned actors to use isolate port scope node: allow one pinned actor to use isolate port scope Sep 14, 2026
@petebacondarwin

Copy link
Copy Markdown
Contributor Author

Closing in favour of #7357

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