fix(client-dotnet): size the safe-unary retry budget for every attempt (#197)

ExecuteSafeUnaryAsync capped the whole retry pipeline at one
DefaultCallTimeout while each attempt carried the same deadline, so a first
attempt ending in DeadlineExceeded spent the entire budget and the retry
never ran. The outer cap is now MaxAttempts x DefaultCallTimeout plus MaxDelay
per backoff (MxGatewayClientRetryPolicy.SafeUnaryBudget), in both
MxGatewayClient and GalaxyRepositoryClient; a budget too large for a
cancellation timer leaves only the per-attempt deadlines.

Tests: MxGatewayClientWireTests.SafeUnaryRetry_AfterDeadlineExceededFirstAttempt_RunsTheRetry
(real gRPC loopback server stalls the first Invoke; fails with Cancelled on
the old code), plus two SafeUnaryBudget unit tests.
This commit is contained in:
Joseph Doherty
2026-11-06 16:07:35 -05:00
parent ff397b27be
commit b9096f7c57
8 changed files with 159 additions and 7 deletions
+5
View File
@@ -122,6 +122,11 @@ The .NET client applies a bounded Polly retry policy only to idempotent calls:
streams, writes, secured writes, authentication, registration, item management,
or subscription changes because those calls can partially succeed in MXAccess.
Each attempt carries its own `DefaultCallTimeout` deadline. The overall budget
for a retried call is `MaxAttempts × DefaultCallTimeout` plus `MaxDelay` for each
backoff, so an attempt that ends in `DeadlineExceeded` leaves the retry its own
full deadline instead of consuming the whole budget.
API key may be loaded from `MXGATEWAY_API_KEY` by the CLI, not implicitly by the
library constructor unless a helper explicitly says it does that.