Add Polly resilience policies

This commit is contained in:
Joseph Doherty
2026-04-27 15:37:56 -04:00
parent d431ff9660
commit bd4a09a35e
22 changed files with 611 additions and 21 deletions
@@ -80,6 +80,65 @@ public sealed class WorkerPipeClientTests
await clientTask;
}
[Fact]
public async Task RunAsync_RetriesUntilPipeServerAppears()
{
string pipeName = $"mxaccess-gateway-test-{Guid.NewGuid():N}";
WorkerOptions workerOptions = new(
"session-1",
pipeName,
GatewayContractInfo.WorkerProtocolVersion,
"nonce-secret");
WorkerFrameProtocolOptions frameOptions = new(workerOptions);
WorkerPipeClient client = new(
logger: null,
connectTimeoutMilliseconds: 1000,
connectAttemptTimeoutMilliseconds: 50,
(stream, options, _) => CreateSession(stream, options));
Task clientTask = client.RunAsync(workerOptions);
await Task.Delay(150);
using NamedPipeServerStream server = new(
pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
await Task.Factory.FromAsync(server.BeginWaitForConnection, server.EndWaitForConnection, null);
WorkerFrameReader reader = new(server, frameOptions);
WorkerFrameWriter writer = new(server, frameOptions);
await writer.WriteAsync(CreateGatewayHello());
Assert.Equal(WorkerEnvelope.BodyOneofCase.WorkerHello, (await reader.ReadAsync()).BodyCase);
Assert.Equal(WorkerEnvelope.BodyOneofCase.WorkerReady, (await reader.ReadAsync()).BodyCase);
await writer.WriteAsync(CreateShutdown());
Assert.Equal(WorkerEnvelope.BodyOneofCase.WorkerShutdownAck, (await reader.ReadAsync()).BodyCase);
await clientTask;
}
[Fact]
public async Task RunAsync_WhenPipeNeverAppears_ThrowsTimeoutException()
{
WorkerOptions workerOptions = new(
"session-1",
$"mxaccess-gateway-test-{Guid.NewGuid():N}",
GatewayContractInfo.WorkerProtocolVersion,
"nonce-secret");
WorkerPipeClient client = new(
logger: null,
connectTimeoutMilliseconds: 100,
connectAttemptTimeoutMilliseconds: 50,
(stream, options, _) => CreateSession(stream, options));
await Assert.ThrowsAsync<TimeoutException>(async () => await client.RunAsync(workerOptions));
}
private static WorkerPipeSession CreateSession(
Stream stream,
WorkerFrameProtocolOptions options)
@@ -97,6 +156,37 @@ public sealed class WorkerPipeClientTests
() => new FakeRuntimeSession());
}
private static WorkerEnvelope CreateGatewayHello()
{
return new WorkerEnvelope
{
ProtocolVersion = GatewayContractInfo.WorkerProtocolVersion,
SessionId = "session-1",
Sequence = 1,
GatewayHello = new GatewayHello
{
SupportedProtocolVersion = GatewayContractInfo.WorkerProtocolVersion,
Nonce = "nonce-secret",
GatewayVersion = "test-gateway",
},
};
}
private static WorkerEnvelope CreateShutdown()
{
return new WorkerEnvelope
{
ProtocolVersion = GatewayContractInfo.WorkerProtocolVersion,
SessionId = "session-1",
Sequence = 2,
WorkerShutdown = new WorkerShutdown
{
GracePeriod = Duration.FromTimeSpan(TimeSpan.FromSeconds(1)),
Reason = "test-complete",
},
};
}
private sealed class FakeRuntimeSession : IWorkerRuntimeSession
{
public Task<WorkerReady> StartAsync(