fix(focas): a caller's own cancellation during connect does not open the backoff window; deterministic concurrent-connect test

Review follow-up on c940349f: a cancelled caller recorded a connect failure, throttling every caller queued
on ConnectGate for ~1 s. The 200 ms settle delay in the concurrent-connect test is replaced by a
TaskCompletionSource the fake connect signals on entry. Both tests verified red with their fix reverted.

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 21:28:00 -04:00
parent c940349fe8
commit 54a00fd760
2 changed files with 49 additions and 6 deletions
@@ -1855,12 +1855,15 @@ public sealed class FocasDriver : IDriver, IReadable, IWritable, ITagDiscovery,
{
await client.ConnectAsync(device.ParsedAddress, _options.Timeout, ct).ConfigureAwait(false);
}
catch
catch (Exception ex)
{
// Dispose only OUR client — never one another path installed meanwhile (recycle/teardown).
client.Dispose();
if (ReferenceEquals(device.Client, client)) device.Client = null;
device.Backoff.RecordFailure(DateTime.UtcNow); // 05/STAB-8: open the backoff window
// The caller's OWN cancellation says nothing about the CNC: do not open the backoff window, or
// every caller queued on ConnectGate behind it would be throttled for ~1 s for nothing.
if (!(ex is OperationCanceledException && ct.IsCancellationRequested))
device.Backoff.RecordFailure(DateTime.UtcNow); // 05/STAB-8: open the backoff window
throw;
}
device.Backoff.RecordSuccess(); // 05/STAB-8: recovery resets the window immediately