fix(runtime): re-provision a driver child after a supervision restart (archreview 03/S6, S16)
This commit is contained in:
@@ -42,6 +42,25 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// restored → Good) — independently of alarm transitions, since a comms-lost driver emits no alarm
|
||||
/// events. Fire-and-forget, mirroring <see cref="DeltaApplied"/>.</summary>
|
||||
public sealed record ConnectivityChanged(string DriverInstanceId, bool Connected);
|
||||
|
||||
/// <summary>
|
||||
/// Sent to the parent from <see cref="PostRestart"/> so the host re-provisions THIS incarnation
|
||||
/// (archreview 03/S6, 03/S16).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A supervision restart recreates the actor object in place: the desired subscription sets are gone
|
||||
/// (they are instance fields), and <c>PreRestart</c> has already run <see cref="PostStop"/> — which
|
||||
/// called <see cref="IDriver.ShutdownAsync"/> on the driver object the Props closure re-uses. Nothing
|
||||
/// else re-sends <see cref="InitializeRequested"/>: its only sender is
|
||||
/// <c>DriverHostActor.SpawnChild</c>, and a restart does NOT respawn (the child's
|
||||
/// <see cref="IActorRef"/> is unchanged, so the host is not otherwise notified that a new incarnation
|
||||
/// exists at all). Without this the restarted child sits in <c>Connecting</c> forever around a
|
||||
/// shut-down driver, with nothing subscribed — silently, since Akka logs the fault but the recovery
|
||||
/// is invisible.
|
||||
/// </remarks>
|
||||
/// <param name="DriverInstanceId">The driver instance that was restarted.</param>
|
||||
/// <param name="Reason">The type name of the exception that tripped supervision, for the host's log.</param>
|
||||
public sealed record ReprovisionRequested(string DriverInstanceId, string Reason);
|
||||
public sealed record ApplyDelta(string DriverConfigJson, CorrelationId Correlation);
|
||||
public sealed record ApplyResult(bool Success, string? Reason, CorrelationId Correlation);
|
||||
/// <summary>
|
||||
@@ -375,6 +394,20 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
Timers.StartPeriodicTimer("health-poll", HealthPollTick.Instance, _healthPollInterval);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// Ask the host to re-provision this incarnation — see <see cref="ReprovisionRequested"/> for why a
|
||||
/// supervision restart otherwise leaves a dead child. <c>base.PostRestart</c> runs first because it
|
||||
/// runs <see cref="PreStart"/>, which re-attaches the rediscovery / host-status sources and restarts
|
||||
/// the health timer; the reprovision is the part <see cref="PreStart"/> cannot do, since only the
|
||||
/// host knows this driver's config and desired set.
|
||||
/// </remarks>
|
||||
protected override void PostRestart(Exception reason)
|
||||
{
|
||||
base.PostRestart(reason);
|
||||
Context.Parent.Tell(new ReprovisionRequested(_driverInstanceId, reason.GetType().Name));
|
||||
}
|
||||
|
||||
private void Stubbed()
|
||||
{
|
||||
// Stubbed drivers accept the standard message contracts but return deterministic
|
||||
|
||||
Reference in New Issue
Block a user