fix(site-runtime): deployment whose Instance Actor dies during init reports Failed, exactly-once reply (S6)
Success now requires BOTH persistence commit AND an InstanceActorInitialized readiness signal from the actor's PreStart — persistence can commit before the actor's async init has run or failed, so persistence alone must not report Success. An actor that dies during init never signals readiness; the Terminated fallback fails that deployment and rolls back the optimistic state. The persisted-row rollback is deferred until the store commits so it cannot race the optimistic write. Deviation from plan Task 15: the plan's swallow-only guard did not handle the persistence-first ordering (empirically the store commits before the Terminated signal, so Success was reported for a dead actor). Added the readiness handshake to make the join deterministic.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Readiness signal an <c>InstanceActor</c> sends to its parent
|
||||
/// <c>DeploymentManagerActor</c> at the very end of a successful <c>PreStart</c> —
|
||||
/// after its child Script/Alarm/NativeAlarm actors have been created and its DCL
|
||||
/// subscriptions issued. If <c>PreStart</c> throws before this point (e.g. a child
|
||||
/// actor cannot be created), the message is never sent and the actor is stopped
|
||||
/// with an <c>ActorInitializationException</c> instead.
|
||||
///
|
||||
/// The Deployment Manager uses it to confirm a deployment only once the Instance
|
||||
/// Actor has actually initialized — SQLite persistence completing is necessary but
|
||||
/// NOT sufficient, because persistence can commit before the actor's asynchronous
|
||||
/// init has run (or failed). Reporting deployment <c>Success</c> is therefore gated
|
||||
/// on BOTH the persistence result AND this signal (S6); an actor that dies during
|
||||
/// init never sends it, so its deployment is failed by the Terminated fallback.
|
||||
/// </summary>
|
||||
/// <param name="InstanceUniqueName">The unique name of the initialized instance.</param>
|
||||
public sealed record InstanceActorInitialized(string InstanceUniqueName);
|
||||
Reference in New Issue
Block a user