Conversation
…nection refused errors Agent-Logs-Url: https://github.com/dapr/dotnet-sdk/sessions/68d785b9-a186-4909-8300-41dafe05dbc0 Co-authored-by: WhitWaldo <2238529+WhitWaldo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dapr/dotnet-sdk/sessions/68d785b9-a186-4909-8300-41dafe05dbc0 Co-authored-by: WhitWaldo <2238529+WhitWaldo@users.noreply.github.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1782 +/- ##
==========================================
+ Coverage 60.95% 61.18% +0.23%
==========================================
Files 284 285 +1
Lines 8358 8405 +47
Branches 965 974 +9
==========================================
+ Hits 5095 5143 +48
+ Misses 3030 3026 -4
- Partials 233 236 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@copilot This does not appear to have improved the situation as most integration tests are failing. For example: |
…rHttpHealthAsync Agent-Logs-Url: https://github.com/dapr/dotnet-sdk/sessions/cce14547-9974-4e12-b562-54edf931d423 Co-authored-by: WhitWaldo <2238529+WhitWaldo@users.noreply.github.com>
The root cause was a distinction between two conditions:
My original fix waited for healthy, but Dapr returns 500 from The correct check to eliminate the "Connection refused" race window is reachable: once Dapr's HTTP server processes any request (even one that returns 500), both the HTTP and gRPC servers have their handlers installed and are stable. Updated in commit New method |
Intermittent
Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="Error connecting to subchannel.")failures occur becauseDaprdContainer.StartAsyncreturned as soon as the TCP ports accepted a connection — but Dapr continues initializing (connecting to Placement/Scheduler, loading components, starting the workflow engine) after that point, causing a brief window where the gRPC port accepts TCP connections but its request handlers are not yet installed.Description
New
ContainerReadinessProbe(internal static) — consolidates the existing TCP port probe (moved fromDaprdContainer) and adds two new HTTP polling methods:WaitForHttpReachableAsync— returns as soon as any HTTP response is received (including 5xx), only retrying when the connection itself is refused. Used byDaprdContaineras the final readiness gate.WaitForHttpHealthAsync— stricter check that retries until a 2xx response is received. Retained for use cases that require full application health confirmation.DaprdContainer.StartAsync— replaced inlineWaitForTcpPortAsyncwithContainerReadinessProbecalls and appendedWaitForHttpReachableAsyncas the final readiness gate; also removed a deadcatchblock that was swallowing-and-rethrowing with no effect.AssemblyInfo.cs— addsInternalsVisibleTo("Dapr.Testcontainers.Test")so the internal probe class is directly testable.ContainerReadinessProbeTests— 20 unit tests covering TCP, HTTP reachability, and HTTP health probe behaviors: success on any response code, retry-until-reachable, connection-refused retry, timeout expiry, and cancellation across all target frameworks.The key distinction between the two HTTP methods: Dapr returns HTTP 500 from
/v1.0/healthzwhile components are loading or while the connected app hasn't started yet (e.g. in resources-first startup mode whereDaprdContainer.StartAsynccompletes before the web app is launched). UsingWaitForHttpReachableAsyncensures the gRPC handlers are installed without requiring full application health, avoiding false timeouts.Issue reference
Checklist