using System;
namespace ZB.MOM.WW.MxGateway.Worker.Ipc;
/// Configuration options for worker pipe sessions including heartbeat parameters.
public sealed class WorkerPipeSessionOptions
{
/// Default heartbeat interval (5 seconds).
public static readonly TimeSpan DefaultHeartbeatInterval = TimeSpan.FromSeconds(5);
/// Default heartbeat grace period (15 seconds).
public static readonly TimeSpan DefaultHeartbeatGrace = TimeSpan.FromSeconds(15);
///
/// Default defensive ceiling beyond which the watchdog fires
///
/// even while a command is in flight (75 seconds = 5 ×
/// ). See
/// for the rationale.
///
public static readonly TimeSpan DefaultHeartbeatStuckCeiling = TimeSpan.FromSeconds(75);
/// Initializes a new instance of the WorkerPipeSessionOptions class with default values.
public WorkerPipeSessionOptions()
{
HeartbeatInterval = DefaultHeartbeatInterval;
HeartbeatGrace = DefaultHeartbeatGrace;
HeartbeatStuckCeiling = DefaultHeartbeatStuckCeiling;
}
/// Gets or sets the heartbeat interval.
public TimeSpan HeartbeatInterval { get; set; }
/// Gets or sets the heartbeat grace period.
public TimeSpan HeartbeatGrace { get; set; }
///
/// Gets or sets the defensive upper bound on how long the watchdog
/// will suppress its StaHung fault while a command is in
/// flight. Worker-017 suppresses the watchdog when the heartbeat
/// snapshot's CurrentCommandCorrelationId is non-empty so a
/// legitimately slow command (e.g. ReadBulk against many
/// uncached tags) does not self-fault — but a truly stuck
/// synchronous COM call against a dead MXAccess provider leaves
/// CurrentCommandCorrelationId non-empty forever and would
/// permanently defeat the watchdog. HeartbeatStuckCeiling is
/// the upper bound on that suppression: once
/// LastStaActivityUtc has been stale for longer than this
/// ceiling, the watchdog DOES fire StaHung even with a
/// command in flight, on the assumption that no legitimate STA
/// command should run that long without periodically refreshing
/// activity. Default is
/// (75 seconds = 5 × ); raise
/// for deployments that run very long bulk operations.
///
public TimeSpan HeartbeatStuckCeiling { get; set; }
/// Validates the session options.
public void Validate()
{
if (HeartbeatInterval <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(
nameof(HeartbeatInterval),
"Worker heartbeat interval must be greater than zero.");
}
if (HeartbeatGrace <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(
nameof(HeartbeatGrace),
"Worker heartbeat grace must be greater than zero.");
}
if (HeartbeatStuckCeiling <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(
nameof(HeartbeatStuckCeiling),
"Worker heartbeat stuck ceiling must be greater than zero.");
}
if (HeartbeatStuckCeiling <= HeartbeatGrace)
{
throw new ArgumentOutOfRangeException(
nameof(HeartbeatStuckCeiling),
"Worker heartbeat stuck ceiling must be greater than HeartbeatGrace; "
+ "otherwise it would fire before the in-flight-command suppression had any effect.");
}
}
}