From 356f81c0ed2a42c655501e08c795fc036103b4b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 22:39:11 +0000 Subject: [PATCH 1/4] Initial plan From d39e02577a376327217cecb3819b53ba67716196 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 22:54:05 +0000 Subject: [PATCH 2/4] Fix WebAPI sample to use embedded gRPC sidecar Co-authored-by: sophiatev <38052607+sophiatev@users.noreply.github.com> --- samples/WebAPI/Program.cs | 54 +++++++++++++++++-- samples/WebAPI/Properties/launchSettings.json | 23 +------- samples/WebAPI/WebAPI.csproj | 10 ++++ 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/samples/WebAPI/Program.cs b/samples/WebAPI/Program.cs index 111413ee..ca3f4398 100644 --- a/samples/WebAPI/Program.cs +++ b/samples/WebAPI/Program.cs @@ -2,20 +2,62 @@ // Licensed under the MIT License. using System.Text.Json.Serialization; +using DurableTask.Core; +using Grpc.Net.Client; +using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.DurableTask; using Microsoft.DurableTask.Client; +using Microsoft.DurableTask.Testing.Sidecar; +using Microsoft.DurableTask.Testing.Sidecar.Grpc; using Microsoft.DurableTask.Worker; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); -// Add all the generated tasks +// The REST API will listen on port 8080 (HTTP/1.1) and the gRPC sidecar will listen on port 8081 (HTTP/2) +int restPort = 8080; +int grpcPort = 8081; + +// Configure Kestrel with two endpoints: +// - Port 8080 for REST API (HTTP/1.1) +// - Port 8081 for gRPC sidecar (HTTP/2) +builder.WebHost.ConfigureKestrel(options => +{ + options.ListenAnyIP(restPort, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http1; + }); + options.ListenAnyIP(grpcPort, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http2; + }); +}); + +// Create the in-memory orchestration service that will store all orchestration state. +// This eliminates the need for an external gRPC sidecar. +InMemoryOrchestrationService orchestrationService = new(); + +// Register the in-memory orchestration service for the gRPC sidecar +builder.Services.AddSingleton(orchestrationService); +builder.Services.AddSingleton(orchestrationService); +builder.Services.AddSingleton(); +builder.Services.AddGrpc(); + +// Create the gRPC channel that will connect to the embedded sidecar on the gRPC port +GrpcChannel grpcChannel = GrpcChannel.ForAddress($"http://localhost:{grpcPort}"); + +// Add all the generated tasks and configure worker to use the embedded gRPC sidecar builder.Services.AddDurableTaskWorker(builder => { builder.AddTasks(r => r.AddAllGeneratedTasks()); - builder.UseGrpc(); + builder.UseGrpc(grpcChannel); }); -builder.Services.AddDurableTaskClient(b => b.UseGrpc()); +// Configure the durable task client to use the embedded gRPC sidecar +builder.Services.AddDurableTaskClient(b => +{ + b.UseGrpc(grpcChannel); + b.RegisterDirectly(); +}); // Configure the HTTP request pipeline. builder.Services.AddControllers().AddJsonOptions(options => @@ -25,5 +67,9 @@ }); WebApplication app = builder.Build(); + +// Map the gRPC sidecar service endpoint +app.MapGrpcService(); + app.MapControllers(); -app.Run("http://0.0.0.0:8080"); +app.Run(); diff --git a/samples/WebAPI/Properties/launchSettings.json b/samples/WebAPI/Properties/launchSettings.json index e119b069..f39c2c31 100644 --- a/samples/WebAPI/Properties/launchSettings.json +++ b/samples/WebAPI/Properties/launchSettings.json @@ -1,32 +1,13 @@ { "$schema": "https://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:47697", - "sslPort": 44371 - } - }, "profiles": { "WebAPI": { "commandName": "Project", - "launchBrowser": true, - "launchUrl": "weatherforecast", + "launchBrowser": false, "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "DURABLETASK_SIDECAR_ADDRESS": "http://localhost:4001" + "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "https://localhost:7217;http://localhost:5217", "dotnetRunMessages": true - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "weatherforecast", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } } } } \ No newline at end of file diff --git a/samples/WebAPI/WebAPI.csproj b/samples/WebAPI/WebAPI.csproj index 84680817..d101c47d 100644 --- a/samples/WebAPI/WebAPI.csproj +++ b/samples/WebAPI/WebAPI.csproj @@ -9,9 +9,19 @@ + + + + + + + + + From eb95ade483f208bf7768f2acc5379d62f0bdc6d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 22:59:25 +0000 Subject: [PATCH 3/4] Address code review feedback: add clarifying comment and applicationUrl Co-authored-by: sophiatev <38052607+sophiatev@users.noreply.github.com> --- samples/WebAPI/Program.cs | 4 +++- samples/WebAPI/Properties/launchSettings.json | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/WebAPI/Program.cs b/samples/WebAPI/Program.cs index ca3f4398..e4eaa47e 100644 --- a/samples/WebAPI/Program.cs +++ b/samples/WebAPI/Program.cs @@ -42,7 +42,9 @@ builder.Services.AddSingleton(); builder.Services.AddGrpc(); -// Create the gRPC channel that will connect to the embedded sidecar on the gRPC port +// Create the gRPC channel that will connect to the embedded sidecar on the gRPC port. +// Note: GrpcChannel.ForAddress() doesn't establish a connection until a call is made, +// and the DurableTask worker starts making calls after the host is fully started. GrpcChannel grpcChannel = GrpcChannel.ForAddress($"http://localhost:{grpcPort}"); // Add all the generated tasks and configure worker to use the embedded gRPC sidecar diff --git a/samples/WebAPI/Properties/launchSettings.json b/samples/WebAPI/Properties/launchSettings.json index f39c2c31..2d6964b5 100644 --- a/samples/WebAPI/Properties/launchSettings.json +++ b/samples/WebAPI/Properties/launchSettings.json @@ -4,6 +4,7 @@ "WebAPI": { "commandName": "Project", "launchBrowser": false, + "applicationUrl": "http://localhost:8080", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, From 6675ff2547118c4be70ddd80d8d5eead0dcd5652 Mon Sep 17 00:00:00 2001 From: Tomer Rosenthal Date: Tue, 2 Dec 2025 16:37:22 -0800 Subject: [PATCH 4/4] Update samples/WebAPI/Program.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- samples/WebAPI/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/WebAPI/Program.cs b/samples/WebAPI/Program.cs index e4eaa47e..0bfdf968 100644 --- a/samples/WebAPI/Program.cs +++ b/samples/WebAPI/Program.cs @@ -55,10 +55,10 @@ }); // Configure the durable task client to use the embedded gRPC sidecar -builder.Services.AddDurableTaskClient(b => +builder.Services.AddDurableTaskClient(builder => { - b.UseGrpc(grpcChannel); - b.RegisterDirectly(); + builder.UseGrpc(grpcChannel); + builder.RegisterDirectly(); }); // Configure the HTTP request pipeline.