fix(drivers): mid-connect ApplyDelta adopts config in Calculation, refuses it in Galaxy (#664)
AdoptConfigDuringInit re-runs InitializeAsync(newConfig) and acks success, but Calculation and Galaxy ignored the JSON there: Calculation kept its old tag set, and Galaxy connected on its old endpoint. Calculation now rebuilds its tag table from a config with a body (sharing AdoptConfig with ReinitializeAsync and stopping any running timer scheduler first). Galaxy, which cannot hot-swap its options, refuses a non-equivalent one the way ReinitializeAsync does. The actor now sends DeltaApplied once the adopted init succeeds, so a dependency consumer's mux interest is re-registered. Unreachable from deploys since #516. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -221,6 +221,12 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
private readonly ILoggingAdapter _log = Context.GetLogger();
|
||||
private string? _currentConfigJson;
|
||||
|
||||
/// <summary>#664: set when <see cref="AdoptConfigDuringInit"/> adopts a new config mid-connect; the next
|
||||
/// (generation-matched) <see cref="InitializeSucceeded"/> sends <see cref="DeltaApplied"/> to the parent and
|
||||
/// clears it, so a dependency consumer's mux interest is re-registered against the ADOPTED config — the
|
||||
/// same post-reinit notification the Connected <see cref="HandleApplyDeltaAsync"/> path sends.</summary>
|
||||
private bool _adoptedConfigPendingNotify;
|
||||
|
||||
/// <summary>Monotonic token tagging each <see cref="InitializeAsync"/> attempt. An init result is
|
||||
/// honoured only when its generation matches the latest; an older result is from a superseded attempt
|
||||
/// (e.g. an <see cref="ApplyDelta"/> adopted a new config mid-(re)connect) and is dropped. Touched only
|
||||
@@ -468,6 +474,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
if (msg.Generation != _initGeneration) return;
|
||||
_log.Info("DriverInstance {Id}: connected", _driverInstanceId);
|
||||
Become(Connected);
|
||||
NotifyAdoptedConfig();
|
||||
PublishHealthSnapshot();
|
||||
ResubscribeDesired();
|
||||
AttachAlarmSource();
|
||||
@@ -771,6 +778,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
Timers.Cancel("retry-connect");
|
||||
_log.Info("DriverInstance {Id}: reconnected", _driverInstanceId);
|
||||
Become(Connected);
|
||||
NotifyAdoptedConfig();
|
||||
PublishHealthSnapshot();
|
||||
ResubscribeDesired();
|
||||
AttachAlarmSource();
|
||||
@@ -878,9 +886,19 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
_log.Info("DriverInstance {Id}: ApplyDelta during (re)connect — adopting new config, re-initialising now",
|
||||
_driverInstanceId);
|
||||
InitializeAsync(msg.DriverConfigJson);
|
||||
_adoptedConfigPendingNotify = true;
|
||||
Sender.Tell(new ApplyResult(true, "config adopted; reinitializing", msg.Correlation));
|
||||
}
|
||||
|
||||
/// <summary>Send the deferred <see cref="DeltaApplied"/> for a mid-connect adoption (#664) once the driver
|
||||
/// has actually initialised on the adopted config. A no-op otherwise.</summary>
|
||||
private void NotifyAdoptedConfig()
|
||||
{
|
||||
if (!_adoptedConfigPendingNotify) return;
|
||||
_adoptedConfigPendingNotify = false;
|
||||
Context.Parent.Tell(new DeltaApplied(_driverInstanceId));
|
||||
}
|
||||
|
||||
/// <summary>Adopt a new config while Connected, in place, via <see cref="IDriver.ReinitializeAsync"/>.
|
||||
/// <para>#663: every driver's reinit releases its device/session state (#630), so the driver-side data and
|
||||
/// native-alarm subscriptions do not survive it — but this handler used to keep both handles, and the
|
||||
|
||||
Reference in New Issue
Block a user