fix(communication): resolve Communication-002/003 — gRPC reconnect stream cleanup and subscription map safety

This commit is contained in:
Joseph Doherty
2026-05-16 19:33:09 -04:00
parent 87f14c190a
commit 301e7fb854
5 changed files with 134 additions and 7 deletions

View File

@@ -159,6 +159,34 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Equal("corr-1", ctx.MockGrpcClient.SubscribeCalls[1].CorrelationId);
}
[Fact]
public void On_GrpcError_Unsubscribes_Old_Stream_Before_Reconnect()
{
// Communication-002 regression: a reconnect must unsubscribe the previous
// stream so the old node does not keep a zombie relay actor / subscription.
var ctx = CreateBridgeActor();
ctx.CommProbe.ExpectMsg<SiteEnvelope>();
var snapshot = new DebugViewSnapshot(
InstanceName,
new List<AttributeValueChanged>(),
new List<AlarmStateChanged>(),
DateTimeOffset.UtcNow);
ctx.BridgeActor.Tell(snapshot);
AwaitCondition(() => ctx.MockGrpcClient.SubscribeCalls.Count == 1, TimeSpan.FromSeconds(3));
// Simulate gRPC error → reconnect
ctx.MockGrpcClient.SubscribeCalls[0].OnError(new Exception("Stream broken"));
// Should resubscribe...
AwaitCondition(() => ctx.MockGrpcClient.SubscribeCalls.Count == 2, TimeSpan.FromSeconds(5));
// ...and must have unsubscribed the prior correlation ID so the old node's
// relay actor is released rather than left zombie.
Assert.Contains("corr-1", ctx.MockGrpcClient.UnsubscribedCorrelationIds);
}
[Fact]
public void After_MaxRetries_Terminates()
{