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); }