fix(deploy): hold the Applied ack until the address-space apply outcome is known (#601)
DriverHostActor no longer acks Applied the moment the revision advances. It asks OpcUaPublishActor for the outcome (RebuildAddressSpace.ReportOutcome) and acks Applied+Degraded(reason) when the apply was degraded; a missing outcome times out (60 s, inside the coordinator's 2 min deadline) to a degraded ack, never a clean one. Re-dispatching a revision whose apply was degraded or is still unconfirmed re-applies instead of taking the clean idempotent short-circuit - that re-apply is also what repairs the degraded nodes. Tests with a bare publish probe use a clean-outcome auto-pilot probe. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using Akka.Actor;
|
||||
using Akka.TestKit;
|
||||
using ZB.MOM.WW.OtOpcUa.Runtime.OpcUa;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Harness;
|
||||
|
||||
/// <summary>
|
||||
/// Gitea #601 — since the deploy ack waits for <see cref="OpcUaPublishActor"/>'s
|
||||
/// <see cref="OpcUaPublishActor.RebuildCompleted"/> reply, a bare <see cref="TestProbe"/> standing in for the
|
||||
/// publish actor would hold every Applied ack until the outcome timeout (and then ack it degraded). Tests
|
||||
/// that are not ABOUT the ack's honesty use this probe instead: it still records every message exactly
|
||||
/// like a plain probe (the auto-pilot runs in addition to queueing), and answers each
|
||||
/// <see cref="OpcUaPublishActor.RebuildAddressSpace"/> that asks for an outcome with a CLEAN one — the
|
||||
/// reply the real publish actor gives a clean apply.
|
||||
/// </summary>
|
||||
public static class PublishProbes
|
||||
{
|
||||
/// <summary>Creates a publish-actor probe that reports a clean address-space outcome for every rebuild
|
||||
/// carrying <see cref="OpcUaPublishActor.RebuildAddressSpace.ReportOutcome"/>.</summary>
|
||||
/// <param name="kit">The calling TestKit.</param>
|
||||
/// <returns>The probe.</returns>
|
||||
public static TestProbe CreateCleanOutcomePublishProbe(this TestKitBase kit)
|
||||
{
|
||||
var probe = kit.CreateTestProbe();
|
||||
probe.SetAutoPilot(new DelegateAutoPilot((sender, message) =>
|
||||
{
|
||||
if (message is OpcUaPublishActor.RebuildAddressSpace { ReportOutcome: true } rebuild)
|
||||
sender.Tell(new OpcUaPublishActor.RebuildCompleted(
|
||||
rebuild.Correlation, rebuild.DeploymentId, Degraded: false, DegradedReason: null));
|
||||
return AutoPilot.KeepRunning;
|
||||
}));
|
||||
return probe;
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public static class V3ArtifactSeeder
|
||||
TimeSpan? reprovisionBackoff = null,
|
||||
TimeSpan? commsRecoveryAuditDelay = null)
|
||||
{
|
||||
var publish = kit.CreateTestProbe();
|
||||
var publish = kit.CreateCleanOutcomePublishProbe();
|
||||
var (actor, mux, coordinator) =
|
||||
Spawn(kit, db, localNode, publish.Ref, driverFactory, reprovisionBackoff, commsRecoveryAuditDelay);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user