docs: strip task-tracking IDs from code comments and fill missing XML docs
ci / nightly-windev (push) Has been skipped
ci / windows-x86 (push) Successful in 1m16s
ci / java (push) Successful in 2m5s
ci / portable (push) Failing after 5m9s

Tracking IDs are review bookkeeping that rots in shipped source; the rationale they tagged is kept. Comment-only change (CommentChecker 458 -> 16 false positives).
This commit is contained in:
Joseph Doherty
2026-10-07 15:34:32 -04:00
parent f2e0861709
commit f40409a688
115 changed files with 549 additions and 411 deletions
@@ -290,12 +290,6 @@ public sealed class FailoverAlarmConsumer : IMxAccessAlarmConsumer
}
/// <inheritdoc />
/// <remarks>
/// Both values come from ONE call to the active child, so the snapshot
/// and its verdict cannot end up describing different children across a
/// failover. A failover to the subtag standby therefore reports
/// not-truncated — correctly, since that child performs no capped fetch.
/// </remarks>
public IReadOnlyList<MxAlarmSnapshotRecord> SnapshotActiveAlarms(out bool truncated)
{
if (disposed) throw new ObjectDisposedException(nameof(FailoverAlarmConsumer));
@@ -108,12 +108,9 @@ public sealed class LmxSubtagAlarmSource : ISubtagAlarmSource
public event EventHandler<SubtagValueChange>? ValueChanged;
/// <inheritdoc />
/// <remarks>
/// Idempotent per address: an address already advised is skipped
/// rather than re-registered.
/// </remarks>
public void Advise(IReadOnlyCollection<string> itemAddresses)
{
// Idempotent per address: an address already advised is skipped rather than re-registered.
if (itemAddresses is null)
{
throw new ArgumentNullException(nameof(itemAddresses));
@@ -144,12 +141,9 @@ public sealed class LmxSubtagAlarmSource : ISubtagAlarmSource
}
/// <inheritdoc />
/// <remarks>
/// Writes with MXAccess user id 0 — always an unsecured Write, never
/// WriteSecured semantics.
/// </remarks>
public void Write(string itemAddress, object? value)
{
// Writes with MXAccess user id 0 — always an unsecured Write, never WriteSecured semantics.
if (itemAddress is null)
{
throw new ArgumentNullException(nameof(itemAddress));
@@ -85,12 +85,7 @@ public sealed class MxAccessBaseEventSink : IMxAccessEventSink, IWriteCompletion
/// </summary>
public MxAccessValueCache ValueCache => valueCache;
/// <summary>
/// The OnWriteComplete completion cache populated by this sink. Exposed
/// via <see cref="IWriteCompletionCacheProvider"/> so the
/// MxAccessSession can share the same instance with the write command
/// executor's bounded completion wait.
/// </summary>
/// <inheritdoc />
public MxAccessWriteCompletionCache WriteCompletionCache => writeCompletionCache;
/// <inheritdoc />
@@ -1025,7 +1025,7 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
/// <summary>
/// Captures the write-completion baseline for <paramref name="serverHandle"/> /
/// <paramref name="itemHandle"/> immediately before a Write/Write2/WriteSecured/
/// WriteSecured2 COM call. Pumps once first (WRK-32) so an <c>OnWriteComplete</c>
/// WriteSecured2 COM call. Pumps once first so an <c>OnWriteComplete</c>
/// already queued for this handle — most commonly the still-undelivered callback of an
/// earlier write to the same tag that this worker gave up waiting on — folds into the
/// baseline instead of being available to ride this write's reply.
@@ -17,7 +17,7 @@ namespace ZB.MOM.WW.MxGateway.Worker.MxAccess;
/// Ownership invariant: <see cref="Enqueue"/> takes ownership of the
/// <see cref="MxEvent"/> passed to it — it stamps the worker sequence and
/// timestamp on that same instance and enqueues it directly, without
/// cloning (WRK-11). Every caller must therefore pass a freshly built
/// cloning. Every caller must therefore pass a freshly built
/// <see cref="MxEvent"/> that it does not retain, reuse, or mutate after the
/// call returns. All production callers (MxAccessBaseEventSink,
/// MxAccessAlarmEventSink, AlarmCommandHandler) build a new event per
@@ -231,7 +231,7 @@ public sealed class MxAccessEventQueue
// lock, so a large gateway-pulled drain kept the STA's next Enqueue blocked for the whole
// sizing walk — exactly when a burst of COM callbacks needs the lock. Measuring on the
// enqueuing thread is safe on both counts: that thread owns this event exclusively at this
// point, and WRK-11 (see the class remarks) makes the hand-off final — nothing mutates an
// point, and the ownership invariant (see the class remarks) makes the hand-off final — nothing mutates an
// event after Enqueue, so a memoized size can never go stale.
//
// Enqueue itself stamps the worker sequence and worker timestamp, and those must stay under
@@ -263,7 +263,7 @@ public sealed class MxAccessEventQueue
throw new MxAccessEventQueueOverflowException(capacity);
}
// WRK-11: stamp the sequence/timestamp on the caller's own event and
// Stamp the sequence/timestamp on the caller's own event and
// enqueue that same instance under the lock instead of cloning. See
// the ownership invariant on the class summary — the caller hands the
// event over exclusively, so a defensive Clone() here is pure
@@ -374,7 +374,7 @@ public sealed class MxAccessEventQueue
/// <remarks>
/// The size decision happens inside the queue lock, so an event is dequeued only once it is
/// known to fit: an event that does not fit stays at the head for the next call and is never
/// lost (WRK-21). Per-event cost is the serialized <c>WorkerEvent</c> size measured once at
/// lost. Per-event cost is the serialized <c>WorkerEvent</c> size measured once at
/// enqueue time — which already includes the event's own tag and length prefix, the same
/// shape the reply's <c>events</c> repeated field packs it into — plus
/// <see cref="RepeatedFieldOverheadBytes"/> of pure slack, so the running total stays
@@ -528,17 +528,22 @@ public sealed class MxAccessEventQueue
// exactly as before.
private readonly struct QueuedEvent
{
/// <summary>Initializes a queued entry from an event and its serialized size.</summary>
/// <param name="workerEvent">The queued event.</param>
/// <param name="size">The serialized size of the event in bytes.</param>
public QueuedEvent(WorkerEvent workerEvent, int size)
{
Event = workerEvent;
Size = size;
}
// The queued event, returned unchanged by TryDequeue and both Drain overloads.
/// <summary>Gets the queued event, returned unchanged by TryDequeue and both Drain overloads.</summary>
public WorkerEvent Event { get; }
// Serialized size of Event, valid for the queue's whole lifetime because an enqueued event
// is never mutated again (WRK-11).
/// <summary>
/// Gets the serialized size of <see cref="Event"/>, valid for the queue's whole lifetime because an enqueued event
/// is never mutated again.
/// </summary>
public int Size { get; }
}
}
@@ -60,8 +60,8 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession
// the StaCommandDispatcher (so it does not inflate PendingCommandCount or perturb command dispatch
// ordering), which means CaptureHeartbeat would otherwise see no in-flight activity during a long
// poll and the watchdog would fault the session at the 15 s grace instead of the 75 s ceiling
// granted to dispatched commands. Surfacing the poll on the heartbeat closes that asymmetry
// (WRK-27). Volatile: written on the STA thread, read on the heartbeat thread.
// granted to dispatched commands. Surfacing the poll on the heartbeat closes that asymmetry.
// Volatile: written on the STA thread, read on the heartbeat thread.
private volatile bool staAlarmPollInProgress;
private bool disposed;
@@ -204,6 +204,7 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession
/// environment variable; a missing or invalid value falls back to
/// <see cref="MxAccessCommandExecutor.DefaultWriteCompletionTimeout"/>.
/// </summary>
/// <returns>The resolved write-completion timeout.</returns>
internal static TimeSpan ResolveWriteCompletionTimeout()
{
string? value = Environment.GetEnvironmentVariable(WorkerLaunchEnvironment.WriteCompletionWaitMilliseconds);
@@ -344,8 +345,8 @@ public sealed class MxAccessStaSession : IWorkerRuntimeSession
await staRuntime.InvokeAsync(
() =>
{
// Advertise the poll to the watchdog for exactly the span of the COM call
// (WRK-27): set on the STA thread immediately before the affinity check and
// Advertise the poll to the watchdog for exactly the span of the COM call:
// set on the STA thread immediately before the affinity check and
// PollOnce, clear in the finally so a heartbeat captured mid-poll reports
// StaCallInProgress and one captured after does not.
staAlarmPollInProgress = true;
@@ -203,6 +203,9 @@ public sealed class MxAccessWriteCompletionCache
/// </remarks>
private readonly struct CompletionEntry
{
/// <summary>Initializes a completion entry.</summary>
/// <param name="version">The monotonic completion version.</param>
/// <param name="statuses">The statuses reported for the completion.</param>
public CompletionEntry(
ulong version,
RepeatedField<MxStatusProxy> statuses)
@@ -211,8 +214,10 @@ public sealed class MxAccessWriteCompletionCache
Statuses = statuses;
}
/// <summary>Gets the monotonic completion version.</summary>
public ulong Version { get; }
/// <summary>Gets the statuses reported for the completion.</summary>
public RepeatedField<MxStatusProxy> Statuses { get; }
}
}
@@ -152,13 +152,6 @@ public sealed class SubtagAlarmConsumer : IMxAccessAlarmConsumer
}
/// <inheritdoc />
/// <remarks>
/// <paramref name="truncated"/> is always <see langword="false"/>: subtag
/// mode is advise-driven over a fixed watch list, so there is no bulk
/// fetch and no per-fetch cap to hit. Subtag snapshots are lower-fidelity
/// in other ways, which <c>MxAlarmSnapshotRecord.Degraded</c> already
/// reports; truncation is not one of them.
/// </remarks>
public IReadOnlyList<MxAlarmSnapshotRecord> SnapshotActiveAlarms(out bool truncated)
{
truncated = false;
@@ -381,18 +381,6 @@ public sealed class WnWrapAlarmConsumer : IMxAccessAlarmConsumer
}
/// <inheritdoc />
/// <remarks>
/// This is the set the gateway's reconcile pass diffs its cache
/// against, so an alarm missing here is what the gateway reads as a
/// Clear. After a truncated fetch the snapshot deliberately still
/// carries alarms the capped reply could not mention — see
/// <see cref="PollOnce"/>. Erring toward "still active" keeps the feed
/// at-least-once: a stale entry is repaired by the next sub-cap poll,
/// whereas a dropped one is broadcast as a Clear that never happened.
/// The snapshot and <paramref name="truncated"/> are produced under one
/// <c>syncRoot</c> acquisition, the same one <see cref="FoldFetch"/>
/// writes them both under, so no poll can interleave between them.
/// </remarks>
public IReadOnlyList<MxAlarmSnapshotRecord> SnapshotActiveAlarms(out bool truncated)
{
if (disposed) throw new ObjectDisposedException(nameof(WnWrapAlarmConsumer));
@@ -11,7 +11,7 @@ namespace ZB.MOM.WW.MxGateway.Worker.MxAccess;
/// maximum: byte-heavy events (large string or array <c>MxValue</c>s) overshoot the frame max
/// long before the count ceiling is reached, and the writer's per-frame rejection then
/// destroys events that were already removed from the queue. The byte-budgeted drain sizes
/// the reply while draining, so an event that does not fit is never dequeued (WRK-21), and
/// the reply while draining, so an event that does not fit is never dequeued, and
/// this result carries the truncation facts the reply's <c>DiagnosticMessage</c> reports —
/// no contract change is needed to express them.
/// Plain constructor and get-only properties: the worker targets .NET Framework 4.8, which
@@ -11,8 +11,7 @@ public sealed class WorkerRuntimeHeartbeatSnapshot
/// <param name="lastEventSequence">Sequence number of the most recent event.</param>
/// <param name="currentCommandCorrelationId">Correlation ID of the in-flight command.</param>
/// <param name="staCallInProgress">
/// True while an STA call outside the command dispatcher is executing (currently the alarm poll,
/// WRK-27). The watchdog treats this like an in-flight command: it suppresses the stale-STA fault
/// True while an STA call outside the command dispatcher is executing (currently the alarm poll). The watchdog treats this like an in-flight command: it suppresses the stale-STA fault
/// up to the stuck ceiling instead of the shorter grace, so a healthy-but-slow poll does not fault
/// a healthy session. Named generically so any future non-dispatcher STA work reuses it.
/// </param>
@@ -50,7 +49,7 @@ public sealed class WorkerRuntimeHeartbeatSnapshot
/// <summary>
/// Gets a value indicating whether an STA call outside the command dispatcher (the alarm poll) is
/// executing. When true the watchdog grants the poll the same grace-to-ceiling suppression as a
/// dispatched command (WRK-27).
/// dispatched command.
/// </summary>
public bool StaCallInProgress { get; }
}