docs: fill missing XML docs and strip tracking IDs from src comments

Clears CommentChecker findings in src/ (3,280 -> 209, the remainder being false
positives like PLC-5/IEEE-754/M0.0) by adding missing summaries/params/returns,
normalising inheritdoc usage, and removing Gitea/review tracking IDs while keeping
the rationale they annotated. Comment-only: comment-stripped sources are identical
to the parent commit.
This commit is contained in:
Joseph Doherty
2026-10-15 06:14:58 -04:00
parent ebcbd81fca
commit 826312befe
430 changed files with 4434 additions and 3923 deletions
@@ -19,10 +19,13 @@ public sealed class DeviceSessionPool
internal sealed class Entry(CipConnection connection, RequestScheduler scheduler, ConnectionOptions options,
Task predecessorClosed)
{
/// <summary>The shared CIP connection for the device.</summary>
public CipConnection Connection { get; } = connection;
/// <summary>Completes when every earlier connection for this key has finished closing.</summary>
public Task PredecessorClosed { get; } = predecessorClosed;
/// <summary>The request scheduler serializing and packing traffic on <see cref="Connection"/>.</summary>
public RequestScheduler Scheduler { get; } = scheduler;
/// <summary>The options the connection was created with.</summary>
public ConnectionOptions Options { get; } = options;
public int RefCount; // under the pool lock
public bool MismatchLogged; // under the pool lock
@@ -35,6 +38,9 @@ public sealed class DeviceSessionPool
private readonly TimeProvider _time;
private volatile ILogger _logger;
/// <summary>Initializes a new instance of the <see cref="DeviceSessionPool"/> class.</summary>
/// <param name="time">Time source; defaults to <see cref="TimeProvider.System"/>.</param>
/// <param name="logger">Logger for mismatch and close-failure warnings; defaults to a no-op logger.</param>
public DeviceSessionPool(TimeProvider? time = null, ILogger? logger = null)
{
_time = time ?? TimeProvider.System;
@@ -43,6 +49,7 @@ public sealed class DeviceSessionPool
/// <summary>Give <see cref="Shared"/> a logger (it is built before any host exists), so its
/// options-mismatch and close-failure warnings reach the service log. Call once at startup.</summary>
/// <param name="loggerFactory">The factory used to create the shared pool's logger.</param>
public static void ConfigureSharedLogger(ILoggerFactory loggerFactory)
{
ArgumentNullException.ThrowIfNull(loggerFactory);
@@ -61,6 +68,9 @@ public sealed class DeviceSessionPool
/// <summary>Lease the shared connection for <paramref name="key"/>, creating it on first use. Performs
/// no I/O: the connection opens on its first request. When the key already has an entry, that entry's
/// options win; a differing <paramref name="options"/> is logged once per entry.</summary>
/// <param name="key">The device to lease a connection for.</param>
/// <param name="options">The options to open the connection with if the key has no entry yet.</param>
/// <returns>A lease on the device's shared connection.</returns>
public ConnectionLease Acquire(DeviceKey key, ConnectionOptions options)
{
ArgumentNullException.ThrowIfNull(key);
@@ -89,6 +99,10 @@ public sealed class DeviceSessionPool
}
}
/// <summary>Drops one reference on <paramref name="entry"/>; the last release removes it and closes the connection.</summary>
/// <param name="key">The device key the entry belongs to.</param>
/// <param name="entry">The entry whose reference is released.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
internal async ValueTask ReleaseAsync(DeviceKey key, Entry entry)
{
TaskCompletionSource closed;
@@ -128,6 +142,11 @@ public sealed class DeviceSessionPool
/// connection. The connection is disposed even if the scheduler's dispose throws: otherwise its keep-alive
/// would hold the press connection open forever. Never throws; each failure is logged.
/// </summary>
/// <param name="key">The device being closed (for logging).</param>
/// <param name="scheduler">The request scheduler to dispose first.</param>
/// <param name="connection">The connection to dispose after the scheduler.</param>
/// <param name="logger">The logger that receives close failures.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
internal static async Task CloseAsync(DeviceKey key, IAsyncDisposable scheduler, IAsyncDisposable connection, ILogger logger)
{
try { await scheduler.DisposeAsync().ConfigureAwait(false); }
@@ -152,6 +171,10 @@ public sealed class ConnectionLease : IAsyncDisposable
private readonly DeviceSessionPool.Entry _entry;
private int _disposed;
/// <summary>Initializes a new instance of the <see cref="ConnectionLease"/> class.</summary>
/// <param name="pool">The owning pool.</param>
/// <param name="key">The device key leased.</param>
/// <param name="entry">The pool entry this lease references.</param>
internal ConnectionLease(DeviceSessionPool pool, DeviceKey key, DeviceSessionPool.Entry entry)
{
_pool = pool;
@@ -159,6 +182,7 @@ public sealed class ConnectionLease : IAsyncDisposable
_entry = entry;
}
/// <summary>The device this lease is on.</summary>
public DeviceKey Key => _key;
/// <summary>The device's channel. Prefer <see cref="Scheduler"/>: it serializes and packs requests.</summary>
@@ -167,13 +191,15 @@ public sealed class ConnectionLease : IAsyncDisposable
/// <summary>The device's single request scheduler, shared by every lease on the key.</summary>
public RequestScheduler Scheduler => _entry.Scheduler;
/// <summary>Releases the lease; further calls are no-ops.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public ValueTask DisposeAsync() =>
Interlocked.Exchange(ref _disposed, 1) == 0 ? _pool.ReleaseAsync(_key, _entry) : ValueTask.CompletedTask;
/// <summary>
/// Releases this lease without waiting for the teardown — the one release shape both native AB tag
/// runtimes use from their synchronous <c>Dispose</c>, which the drivers call under a per-tag lock
/// (Gitea #579). Idempotent, like <see cref="DisposeAsync"/>.
/// runtimes use from their synchronous <c>Dispose</c>, which the drivers call under a per-tag lock.
/// Idempotent, like <see cref="DisposeAsync"/>.
/// </summary>
/// <remarks>
/// <para>Nothing is lost by not waiting. The release's bookkeeping — the ref-count drop and, for the