Skip to content

feat: recognize the native worker runtime (gRPC durable protocol)#3457

Open
ahmedmuhsin wants to merge 3 commits into
Azure:devfrom
ahmedmuhsin:ahmedmuhsin/go-durable-grpc
Open

feat: recognize the native worker runtime (gRPC durable protocol)#3457
ahmedmuhsin wants to merge 3 commits into
Azure:devfrom
ahmedmuhsin:ahmedmuhsin/go-durable-grpc

Conversation

@ahmedmuhsin

@ahmedmuhsin ahmedmuhsin commented Jun 18, 2026

Copy link
Copy Markdown

Summary

Teaches the host to recognize the native worker runtime (FUNCTIONS_WORKER_RUNTIME=native, what the Go worker reports) and route it through the gRPC durable protocol (MiddlewarePassthrough) instead of the legacy HTTP-correlation shim. It also recognizes golang defensively.

This is the host side of Phase 1 of Durable Functions for the Go worker. The worker side is Azure/azure-functions-golang-worker#44, which has the full design write-up for how durable runs on the Go worker. The two are meant to be reviewed and merged together. Without this change the host fails to parse the runtime value, falls back to the HTTP shim, and the durable bindings (orchestrationTrigger, activityTrigger, durableClient) never bind for the Go worker.

Why gRPC for this runtime

Native out-of-process workers talk to the durable extension over the local gRPC sidecar (TaskHubSidecarService), the same path dotnet-isolated and Java use, not the legacy HTTP shim. So native and golang should land in the existing gRPC branch alongside the other compiled and newer-SDK runtimes, with the local HTTP RPC endpoint disabled for them.

Changes

  • IPlatformInformation / WorkerRuntimeType. Add Native (parses native, the primary value) and keep Golang (parses golang, defensive).
  • DurableTaskExtension. Both runtimes select the gRPC MiddlewarePassthrough protocol, and LocalRpcEndpointEnabled is false for them since native workers use the gRPC sidecar exclusively.
  • AzureStorageDurabilityProviderFactory. Default UseSeparateQueueForEntityWorkItems to true for the new runtimes, matching the other gRPC-based runtimes.

Tests

  • TestNativeRuntime_SelectsGrpcProtocol asserts Native and Golang pick MiddlewarePassthrough rather than the HTTP shim.
  • GrpcRuntimes_UseSeparateQueueForEntityWorkItems plus an in-process .NET counter-test pin the entity-queue default for the new runtimes.
  • Both pass on net8.0 and net10.0.

Validation

With this change present in the host, the Go worker's HelloCities and ProcessExpense orchestrations run to Completed on a real host (Core Tools 4.12.0).

Related PRs

Copilot AI review requested due to automatic review settings June 18, 2026 19:36

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.

Pull request overview

Adds host-side recognition of the Go worker’s FUNCTIONS_WORKER_RUNTIME values (native primarily, and golang defensively) so Durable Functions selects the gRPC durable protocol (MiddlewarePassthrough) instead of falling back to the legacy HTTP-correlation shim, enabling durable bindings to work for the native worker runtime.

Changes:

  • Extend WorkerRuntimeType to include Native and Golang.
  • Route Native/Golang runtimes through the gRPC protocol path in DurableTaskExtension, including disabling the legacy local HTTP RPC endpoint for them.
  • Update Azure Storage durability-provider factory defaults to match the gRPC-based runtime set.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/WebJobs.Extensions.DurableTask/IPlatformInformation.cs Adds WorkerRuntimeType.Native and WorkerRuntimeType.Golang enum values with doc comments.
src/WebJobs.Extensions.DurableTask/DurableTaskExtension.cs Treats Native/Golang as gRPC (MiddlewarePassthrough) runtimes and disables the local HTTP RPC endpoint for them.
src/WebJobs.Extensions.DurableTask/AzureStorageDurabilityProviderFactory.cs Aligns entity work-item queue behavior defaults for Native/Golang with other gRPC-based runtimes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/WebJobs.Extensions.DurableTask/DurableTaskExtension.cs Outdated
Comment thread src/WebJobs.Extensions.DurableTask/DurableTaskExtension.cs
Add WorkerRuntimeType.Native (and Golang) and treat them like the other
gRPC-protocol runtimes (.NET isolated, Java) so Durable Functions works for
the Azure Functions Go worker.

The Go worker runs under the native worker model: its app sets
FUNCTIONS_WORKER_RUNTIME to "native" (see the worker's samples and
TECHNICAL_SPEC), and the worker provider declares "language": "golang". The
durable extension reads FUNCTIONS_WORKER_RUNTIME via GetWorkerRuntimeType,
so it sees "native". Some host builds surface "golang" instead (the worker's
integration tests launch func with FUNCTIONS_WORKER_RUNTIME=golang), so both
values are recognized; both identify the Go native worker, which uses the
gRPC out-of-process protocol exclusively (never the legacy HTTP shim).

- IPlatformInformation: new WorkerRuntimeType.Native and Golang. The host
  parses FUNCTIONS_WORKER_RUNTIME via Enum.TryParse(value.Replace("-",""),
  ignoreCase), so "native"/"golang" map to these values.
- DurableTaskExtension: select the gRPC (MiddlewarePassthrough) protocol for
  Native/Golang, alongside DotNetIsolated/Java/Custom. This routes
  orchestrator/activity execution through OutOfProcMiddleware's trigger
  dispatch and stands up the local gRPC server the worker's durable client
  connects to (delivered to the worker as the DurableClient binding's
  rpcBaseUrl). Also mark them as not needing the legacy local HTTP RPC
  endpoint.
- AzureStorageDurabilityProviderFactory: include Native/Golang in the set of
  runtimes that use a separate queue for entity work items, consistent with
  the other gRPC-protocol runtimes.

Execution remains trigger-replay: the host invokes the orchestration/
activity trigger over FunctionRpc with the encoded request and reads the
worker's encoded response, exactly as for .NET isolated and Java. The gRPC
server stays management-only (it does not serve a work-item stream).
… comment

Address review feedback on the native-runtime recognition change:

- Update the protocol-selection comment to reflect that native (Go) and custom-handler runtimes also use the gRPC MiddlewarePassthrough protocol, not just .NET isolated and Java.

- Add unit tests asserting Native/Golang select MiddlewarePassthrough (not the legacy HTTP shim).

- Add unit tests asserting Native/Golang default UseSeparateQueueForEntityWorkItems=true, with an in-proc .NET counter-test.

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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment on lines 59 to 63
/// <summary>
/// Custom handler (see https://learn.microsoft.com/en-us/azure/azure-functions/functions-custom-handlers).
/// </summary>
Custom,

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.

3 participants