feat(site-runtime): TagSubscribeRetryMaxIntervalMs + TagSubscribeInFlightCeilingMs options (Lever 1, validated)
This commit is contained in:
@@ -112,13 +112,34 @@ public class SiteRuntimeOptions
|
||||
public int ConfigFetchTimeoutSeconds { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Fixed interval (ms) at which an Instance Actor re-sends a tag-subscribe
|
||||
/// request that either failed or whose response was lost (S4/UA6). The retry is
|
||||
/// armed on every send and cancelled on the first Success reply, so it closes
|
||||
/// both the failed-response and the lost-response gaps. Default: 5000ms.
|
||||
/// Floor interval (ms) at which an Instance Actor re-sends a tag-subscribe request
|
||||
/// that either failed or whose response was lost (S4/UA6). The retry is armed on
|
||||
/// every send and cancelled on the first Success reply. As of Lever 1 (2026-08-28,
|
||||
/// MxGateway subscribe-storm prevention) it is the FLOOR of an exponential backoff:
|
||||
/// each failed/lost attempt doubles the interval (±20 % jitter) up to
|
||||
/// <see cref="TagSubscribeRetryMaxIntervalMs"/>, and a Success or a connection
|
||||
/// returning to Good quality resets it here. Default: 5000ms.
|
||||
/// </summary>
|
||||
public int TagSubscribeRetryIntervalMs { get; set; } = 5000;
|
||||
|
||||
/// <summary>
|
||||
/// Ceiling (ms) of the tag-subscribe retry backoff. Must be >=
|
||||
/// <see cref="TagSubscribeRetryIntervalMs"/>; equal makes the interval fixed
|
||||
/// (pre-Lever-1 behaviour). Default: 60000ms.
|
||||
/// </summary>
|
||||
public int TagSubscribeRetryMaxIntervalMs { get; set; } = 60000;
|
||||
|
||||
/// <summary>
|
||||
/// How long (ms) an outstanding tag-subscribe request blocks a new one for the
|
||||
/// same connection. While a request is in flight and younger than this, a retry
|
||||
/// tick only re-arms the watchdog instead of issuing a duplicate subscribe — this
|
||||
/// is what stops a slow gateway from receiving a fresh N-tag subscribe every
|
||||
/// interval on top of the one it is still processing. Once older than this the
|
||||
/// reply is presumed lost and a new request is allowed. Size it above the
|
||||
/// gateway's per-command deadline (MxGateway default 30 s). Default: 45000ms.
|
||||
/// </summary>
|
||||
public int TagSubscribeInFlightCeilingMs { get; set; } = 45000;
|
||||
|
||||
/// <summary>
|
||||
/// Grace period (ms) after a script's execution timeout elapses before the
|
||||
/// stuck-script watchdog declares the script's dedicated thread blocked and
|
||||
|
||||
@@ -79,6 +79,16 @@ public sealed class SiteRuntimeOptionsValidator : OptionsValidatorBase<SiteRunti
|
||||
$"(was {options.TagSubscribeRetryIntervalMs}); a zero interval hot-loops the tag-subscribe " +
|
||||
"retry and a negative one throws inside the Instance Actor's retry scheduling.");
|
||||
|
||||
builder.RequireThat(options.TagSubscribeRetryMaxIntervalMs >= options.TagSubscribeRetryIntervalMs,
|
||||
$"ScadaBridge:SiteRuntime:TagSubscribeRetryMaxIntervalMs must be >= TagSubscribeRetryIntervalMs " +
|
||||
$"(was {options.TagSubscribeRetryMaxIntervalMs} vs {options.TagSubscribeRetryIntervalMs}); " +
|
||||
"it is the ceiling of the tag-subscribe retry backoff.");
|
||||
|
||||
builder.RequireThat(options.TagSubscribeInFlightCeilingMs > 0,
|
||||
$"ScadaBridge:SiteRuntime:TagSubscribeInFlightCeilingMs must be greater than 0 " +
|
||||
$"(was {options.TagSubscribeInFlightCeilingMs}); it bounds how long an unanswered tag-subscribe " +
|
||||
"blocks a duplicate for the same connection.");
|
||||
|
||||
builder.RequireThat(options.StuckScriptGraceMs >= 0,
|
||||
$"ScadaBridge:SiteRuntime:StuckScriptGraceMs must be >= 0 " +
|
||||
$"(was {options.StuckScriptGraceMs}); a negative grace throws inside the stuck-script watchdog's delay.");
|
||||
|
||||
Reference in New Issue
Block a user