namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer;
///
/// Configuration options for the Data Connection Layer.
///
public class DataConnectionOptions
{
/// Fixed interval between reconnect attempts after disconnect.
public TimeSpan ReconnectInterval { get; set; } = TimeSpan.FromSeconds(5);
///
/// Floor interval for retrying failed tag path resolution. The retry backs off
/// exponentially (doubling per fully-failed round) up to
/// , and resets to this floor as soon as
/// any tag resolves or the connection reconnects.
///
public TimeSpan TagResolutionRetryInterval { get; set; } = TimeSpan.FromSeconds(10);
///
/// Ceiling for the exponential tag-resolution retry backoff. A dead device with
/// thousands of unresolved tags would otherwise probe forever at full width every
/// .
///
public TimeSpan TagResolutionRetryMaxInterval { get; set; } = TimeSpan.FromMinutes(5);
///
/// Number of tags per adapter subscribe round trip on the batch subscribe path
/// (initial subscribe, reconnect re-subscribe, tag-resolution probes).
///
public int SubscribeBatchSize { get; set; } = 500;
///
/// Delay inserted BETWEEN reconnect re-subscribe chunks so a site-wide reconnect
/// paces the device instead of issuing one task per tag in a tight loop. Not applied
/// on the instance-driven subscribe path — the Deployment Manager already staggers
/// instance startup there, and double-staggering would only slow failover.
///
public TimeSpan SubscribeBatchDelay { get; set; } = TimeSpan.FromMilliseconds(50);
///
/// Number of tags per seed-read chunk. Moderate on purpose: chunking plus the
/// per-chunk answers the "some gateways time out on a
/// large batch" caveat that originally motivated per-tag seed reads.
///
public int SeedReadBatchSize { get; set; } = 250;
/// Maximum seed-read chunks in flight concurrently.
public int SeedReadMaxParallelism { get; set; } = 4;
///
/// Wall-clock deadline for the WHOLE seed (all chunks and all retry rounds). On
/// expiry the remaining tags are logged and stay Uncertain until a change
/// notification arrives — the same outcome as exhausting
/// .
///
public TimeSpan SeedOverallTimeout { get; set; } = TimeSpan.FromSeconds(120);
///
/// Coalescing window for pushing tag-quality counters to the health collector.
/// Counter math stays per message; only the collector push is deferred, and only
/// when a genuine quality transition occurred. Health reports poll at 30s, so a
/// short window loses nothing. Disconnect / unsubscribe / reconnect-reset flushes
/// stay synchronous.
///
public TimeSpan QualityFlushInterval { get; set; } = TimeSpan.FromSeconds(1);
///
/// Maximum in-flight supervisory advise commands when the MxGateway adapter has no
/// write-user context. The gateway worker has no BULK supervisory advise, so the
/// client pipelines per-item advises after one bulk AddItem instead of issuing them
/// serially.
///
public int MxSupervisoryAdviseParallelism { get; set; } = 16;
/// Timeout for synchronous write operations to devices.
public TimeSpan WriteTimeout { get; set; } = TimeSpan.FromSeconds(30);
///
/// Per-tag timeout applied to each
/// call on the initial-subscribe seed path (and reconnect re-seed). A hung device read would
/// otherwise delay SubscribeCompleted and its acknowledgement indefinitely. On timeout
/// the tag is treated the same as any other failed seed read — it stays in the pending set and
/// is retried up to , then left Uncertain until a change
/// notification arrives.
///
public TimeSpan SeedReadTimeout { get; set; } = TimeSpan.FromSeconds(30);
///
/// Minimum time a connection must stay up before it is considered stable.
/// If a connection drops before this threshold, it counts as an unstable
/// disconnect toward the failover retry count.
///
public TimeSpan StableConnectionThreshold { get; set; } = TimeSpan.FromSeconds(60);
///
/// Total number of attempts the seed read makes per tag
/// before giving up. The initial subscribe seed (and the reconnect re-seed) reads
/// each just-advised tag to capture its current value; on a cold/fresh advise the
/// read can race the subscription and return an empty/failed result. A STATIC tag
/// (one that never fires another OnDataChange) would then stay Uncertain forever,
/// because its bridge value depends entirely on that seed. Re-reading the still-empty
/// subset a bounded number of times lets the advise warm up. Minimum 1 (1 = single
/// read, no retry).
///
public int SeedReadMaxAttempts { get; set; } = 3;
///
/// Delay between seed-read attempts for the tags that have
/// not yet returned a usable value. Applied once per round across the whole pending
/// subset, so the total added latency is bounded to
/// (SeedReadMaxAttempts - 1) × SeedReadRetryDelay regardless of tag count.
///
public TimeSpan SeedReadRetryDelay { get; set; } = TimeSpan.FromMilliseconds(250);
}