Skip to content

feat(worker-proxy): relay extension RPC streams - #11959

Open
Jacob Viau (jviau) wants to merge 7 commits into
devfrom
u/jviau/relay-extension-rpc-streams
Open

feat(worker-proxy): relay extension RPC streams#11959
Jacob Viau (jviau) wants to merge 7 commits into
devfrom
u/jviau/relay-extension-rpc-streams

Conversation

@jviau

Copy link
Copy Markdown
Contributor

Issue describing the changes in this PR

N/A. Preceding stack layer: #11958.

This layer adds only the WorkerProxy multiplexed extension-RPC transport and runtime-facing ExtensionRpc stream service. It ports physical-stream negotiation and lifecycle, logical-call routing, timeout propagation, byte-credit flow control, reconnect/session closure, and relay registration. It does not add extension gRPC ingress, telemetry, or host-side dispatch/catalog behavior.

Pull request checklist

IMPORTANT: Currently, changes must be backported to the in-proc branch to be included in Core Tools and non-Flex deployments.

  • Backporting to the in-proc branch is not required
    • Otherwise: Link to backporting PR
  • My changes do not require documentation changes
    • Otherwise: Documentation issue linked to PR
  • My changes should not be added to the release notes for the next release
    • Otherwise: I've added my notes to release_notes.md
  • My changes do not need to be backported to a previous version
    • Otherwise: Backport tracked by issue/PR #issue_or_pr
  • My changes do not require diagnostic events changes
    • Otherwise: I have added/updated all related diagnostic events and their documentation (Documentation issue linked to PR)
  • I have added all required tests (Unit tests, E2E tests)

Additional information

Validation:

  • dotnet test test\Functions.WorkerProxy.Tests\Functions.WorkerProxy.Tests.csproj --no-restore --verbosity minimal
  • dotnet build src\Functions.WorkerProxy\Functions.WorkerProxy.csproj --no-restore --configuration Release --verbosity minimal

@jviau
Jacob Viau (jviau) requested a review from a team as a code owner September 1, 2026 21:19
@jviau Jacob Viau (jviau) added the compute-separation Compute separation / external worker support label Sep 1, 2026
Copilot AI lite review requested due to automatic review settings September 2, 2026 16:10
@jviau
Jacob Viau (jviau) force-pushed the u/jviau/relay-extension-rpc-streams branch from ab3e546 to 7217b43 Compare September 2, 2026 16:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The current stream/session lifecycle and gRPC error-surfacing behavior has correctness/operational gaps that should be addressed before merge.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds the WorkerProxy-side transport for multiplexed Extension RPC, including a runtime-facing gRPC service that attaches a single physical stream to a coordinator and supports worker-originated logical calls with timeout propagation and byte-credit flow control.

Changes:

  • Introduces ExtensionRpcStreamCoordinator/ExtensionRpcStream/ExtensionCall to manage a single physical stream, logical-call routing, negotiation gating, and outbound/inbound message piping.
  • Adds ExtensionRpcRelay gRPC service and registers it in WorkerProxyApplication.
  • Adds ExtensionRpcTransportTests validating negotiation, call opening, credit-window blocking, and session closure behavior.
File summaries
File Description
test/Functions.WorkerProxy.Tests/ExtensionRpcTransportTests.cs Adds unit tests for coordinator negotiation, call routing, flow control, and relay shutdown behavior.
src/Functions.WorkerProxy/WorkerProxyApplication.cs Registers the extension RPC coordinator/relay and maps the new gRPC service endpoint.
src/Functions.WorkerProxy/NumberExtensions.cs Adds invariant numeric formatting helpers used for protocol IDs and timeout formatting.
src/Functions.WorkerProxy/ExtensionRpcStreamLease.cs Adds an async-disposable lease to manage coordinator registration/unregistration of the physical stream.
src/Functions.WorkerProxy/ExtensionRpcStreamCoordinator.cs Implements single-stream coordination, negotiation gating, call opening, and grpc-timeout propagation/formatting.
src/Functions.WorkerProxy/ExtensionRpcStream.cs Implements the physical stream abstraction, outbound queueing (Hello), inbound lifecycle handling, and logical call registration.
src/Functions.WorkerProxy/ExtensionRpcRelay.cs Implements the runtime-facing ExtensionRpc gRPC service and relays inbound/outbound stream messages.
src/Functions.WorkerProxy/ExtensionRpcCreditWindow.cs Implements byte-credit flow-control window used by logical calls.
src/Functions.WorkerProxy/ExtensionCall.cs Implements a logical call with inbound buffering and request credit reservation for Data messages.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Functions.WorkerProxy/ExtensionRpc/ExtensionRpcRelay.cs
@jviau
Jacob Viau (jviau) force-pushed the u/jviau/relay-extension-rpc-streams branch 2 times, most recently from 7217b43 to 5ac0c61 Compare September 2, 2026 17:20
Base automatically changed from u/jviau/extension-rpc-protocol to dev September 2, 2026 18:27
@jviau
Jacob Viau (jviau) force-pushed the u/jviau/relay-extension-rpc-streams branch from 5ac0c61 to 7e2043a Compare September 2, 2026 18:27
@jviau
Jacob Viau (jviau) requested a lite review from Copilot September 2, 2026 18:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

There are correctness/robustness issues (timeout exception semantics and call lifecycle cleanup) that should be addressed before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread src/Functions.WorkerProxy/ExtensionCall.cs
Comment thread src/Functions.WorkerProxy/ExtensionRpcStreamCoordinator.cs Outdated
Comment thread src/Functions.WorkerProxy/WorkerProxyApplication.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

A call deadline provided via start.Timeout is not enforced while waiting for stream negotiation, which can cause OpenExtensionCallAsync to block past (or indefinitely beyond) the intended timeout.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/Functions.WorkerProxy/ExtensionRpcStreamCoordinator.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

There are correctness/robustness issues in the new relay and tests (gRPC status code semantics, exception masking in cleanup, and flaky/misleading timeout assertions) that should be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 4
  • Review effort level: Lite

Comment thread src/Functions.WorkerProxy/ExtensionRpc/ExtensionRpcRelay.cs
Comment thread src/Functions.WorkerProxy/ExtensionRpc/ExtensionRpcRelay.cs Outdated
Comment thread test/Functions.WorkerProxy.Tests/ExtensionRpcTransportTests.cs Outdated
Comment thread test/Functions.WorkerProxy.Tests/ExtensionRpcTransportTests.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The negotiation state in ExtensionRpcStream is accessed across threads without synchronization, which can cause stale reads and incorrect readiness behavior.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Functions.WorkerProxy/ExtensionRpc/ExtensionRpcStream.cs:30

  • _ready is written from the inbound relay reader task and read from other threads (e.g., coordinator/open-call paths) without any synchronization. This can lead to stale reads (e.g., IsReady never observing negotiation completion) or a spurious "not ready" failure even after Ready is received. Make _ready volatile or use Volatile.Read/Write to establish the required memory barriers for cross-thread visibility.
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The current call-open/write paths don’t reliably observe physical-stream cancellation, which can cause hangs or incorrect behavior during disconnect/reconnect scenarios.

Review details

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/Functions.WorkerProxy/ExtensionRpc/ExtensionCall.cs:85

  • Writes can block indefinitely if the physical stream ends while waiting for flow-control credits or while queueing to the outbound channel, because this method only observes the caller-provided cancellationToken and does not also observe the stream’s cancellation token. This can hang callers that use CancellationToken.None (or a token unrelated to the stream) during disconnect/reconnect scenarios.
    src/Functions.WorkerProxy/ExtensionRpc/ExtensionRpcStreamCoordinator.cs:112
  • OpenExtensionCallAsync intends to retry when the transport ends (it catches OperationCanceledException when stream.CancellationToken is canceled), but the call into stream.OpenExtensionCallAsync only uses the caller’s cancellationToken. This means stream disconnects may not cancel the open/write path promptly (and the OCE retry path may never trigger), allowing calls to be opened/writes to be queued against a dead stream until it’s fully closed.
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@jviau
Jacob Viau (jviau) requested a lite review from Copilot September 3, 2026 18:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

There is a build-breaking missing namespace import for ToStringInvariant() usage in ExtensionRpcStreamCoordinator.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Lite

@jviau
Jacob Viau (jviau) force-pushed the u/jviau/relay-extension-rpc-streams branch from 926a2b0 to 70f6e84 Compare September 4, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compute-separation Compute separation / external worker support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants