fix(deploy): derive the apply-outcome timeout from central's apply deadline (105 s) and name a timeout reason distinctly (#601 review)
60 s labelled a slow-but-clean large rebuild degraded. The deadline moves to a shared Commons DeployTimings constant that ConfigPublishCoordinator reads, and the node's timeout is deadline - 15 s margin, so the held ack still lands in time. A timed-out ack's reason now says the outcome was not reported in time, distinct from a real sink failure. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -57,7 +57,9 @@ public sealed class ConfigPublishCoordinator : ReceiveActor, IWithTimers
|
||||
{
|
||||
public const string DeploymentsTopic = "deployments";
|
||||
public const string DeploymentAcksTopic = "deployment-acks";
|
||||
public static readonly TimeSpan DefaultApplyDeadline = TimeSpan.FromMinutes(2);
|
||||
/// <summary>Central's apply deadline — the shared <see cref="DeployTimings.ApplyDeadline"/>, which the node's
|
||||
/// apply-outcome timeout is derived from (Gitea #601).</summary>
|
||||
public static readonly TimeSpan DefaultApplyDeadline = DeployTimings.ApplyDeadline;
|
||||
|
||||
private readonly IDbContextFactory<OtOpcUaConfigDbContext> _dbFactory;
|
||||
private readonly TimeSpan _applyDeadline;
|
||||
|
||||
@@ -89,13 +89,19 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers, IWithUnboundedS
|
||||
/// outcome (<see cref="OpcUa.OpcUaPublishActor.RebuildCompleted"/>) before it is sent anyway.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Deliberately well inside the coordinator's apply deadline
|
||||
/// (<c>ConfigPublishCoordinator.DefaultApplyDeadline</c>, 2 min, which also has to cover the artifact
|
||||
/// read/fetch): a hung or very slow apply must still produce an ack before central times the
|
||||
/// deployment out. An ack sent on this timeout is marked <b>degraded</b> ("outcome unknown"), never
|
||||
/// clean — the revision did advance, but nobody has confirmed the address space matches it.
|
||||
/// Derived from central's apply deadline (<see cref="DeployTimings.ApplyDeadline"/>, 2 min — the same
|
||||
/// constant <c>ConfigPublishCoordinator.DefaultApplyDeadline</c> reads) minus
|
||||
/// <see cref="DeployTimings.ApplyOutcomeSafetyMargin"/> (15 s) = 105 s: long enough that a
|
||||
/// slow-but-clean rebuild of a large address space is not labelled degraded, short enough that the ack
|
||||
/// still lands before central times the deployment out. An ack sent on this timeout is marked
|
||||
/// <b>degraded</b> with a reason starting <see cref="OutcomeNotReportedReasonPrefix"/>, never clean —
|
||||
/// the revision did advance, but nobody has confirmed the address space matches it.
|
||||
/// </remarks>
|
||||
public static readonly TimeSpan DefaultApplyOutcomeTimeout = TimeSpan.FromSeconds(60);
|
||||
public static readonly TimeSpan DefaultApplyOutcomeTimeout = DeployTimings.ApplyOutcomeTimeout;
|
||||
|
||||
/// <summary>Gitea #601 — the reason prefix of a degraded ack sent because the outcome TIMED OUT, so an
|
||||
/// operator can tell "not reported in time" from a real sink failure.</summary>
|
||||
public const string OutcomeNotReportedReasonPrefix = "address-space apply outcome not reported in time";
|
||||
|
||||
/// <summary>Minimum interval between two supervision reprovisions of the SAME driver child (archreview
|
||||
/// review F3). Akka's default decider restarts a faulting child immediately and without limit, and the
|
||||
@@ -2576,7 +2582,7 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers, IWithUnboundedS
|
||||
if (!_pendingAcks.Remove(msg.Correlation, out var pending)) return;
|
||||
|
||||
ReleasePendingAck(pending, degraded: true,
|
||||
$"the address-space apply did not report an outcome within {_applyOutcomeTimeout.TotalSeconds:0}s; it may still be running or may have been lost");
|
||||
$"{OutcomeNotReportedReasonPrefix} ({_applyOutcomeTimeout.TotalSeconds:0}s) — no sink failure was observed; the apply may still be running (slow) or its outcome was lost");
|
||||
}
|
||||
|
||||
private void ReleasePendingAck(PendingAck pending, bool degraded, string? reason)
|
||||
|
||||
Reference in New Issue
Block a user