docs(src): add missing XML docs and strip tracking-ID comments
Sweep of 203 source files resolving CommentChecker findings: add <summary>/<param>/<returns>/<inheritdoc> where missing, and remove resolved task/issue tracking markers (Tests-NNN, Worker-NNN, Server-NNN, Task N) from code comments. Comment/doc-only — no logic changes. Server+Tests build clean under TreatWarningsAsErrors.
This commit is contained in:
@@ -28,8 +28,7 @@ public sealed class GatewaySession
|
||||
// True once at least one external subscriber attached SUCCESSFULLY. Detach-grace's
|
||||
// "last subscriber dropped" stamp (see DetachEventSubscriber) is gated on this so a
|
||||
// FAILED first attach — which still runs the rollback DetachEventSubscriber from the
|
||||
// attach catch path — does not push a never-subscribed session into the grace window
|
||||
// (Server-055).
|
||||
// attach catch path — does not push a never-subscribed session into the grace window.
|
||||
private bool _everHadEventSubscriber;
|
||||
private SessionEventDistributor? _eventDistributor;
|
||||
private bool _eventDistributorStarted;
|
||||
@@ -115,7 +114,7 @@ public sealed class GatewaySession
|
||||
/// </param>
|
||||
/// <param name="detachGrace">
|
||||
/// Retention window kept after the last external (gRPC) event subscriber drops, so a
|
||||
/// client can reconnect (Task 12). When the window is positive and the active external
|
||||
/// client can reconnect. When the window is positive and the active external
|
||||
/// subscriber count falls to zero, the session stays <see cref="SessionState.Ready"/>
|
||||
/// and records a detached timestamp; the lease monitor closes it once the window
|
||||
/// elapses with no subscriber having re-attached. <see cref="TimeSpan.Zero"/> (the
|
||||
@@ -389,7 +388,7 @@ public sealed class GatewaySession
|
||||
/// session by walking it back to <see cref="SessionState.Ready"/> or any earlier
|
||||
/// state. Both close-related writes (<c>Closing</c> and <c>Closed</c>) go through
|
||||
/// <c>_syncRoot</c> just like every other state read/write, closing the split-lock
|
||||
/// race called out in Server-015.
|
||||
/// race.
|
||||
/// </remarks>
|
||||
public void TransitionTo(SessionState nextState)
|
||||
{
|
||||
@@ -420,13 +419,13 @@ public sealed class GatewaySession
|
||||
/// Transitions the session to the Ready state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On becoming Ready the session starts its internal dashboard mirror (Task 6) when a
|
||||
/// On becoming Ready the session starts its internal dashboard mirror when a
|
||||
/// dashboard broadcaster was supplied. The mirror registers an internal subscriber on
|
||||
/// the distributor and starts the pump <em>before</em> any gRPC client attaches, so the
|
||||
/// dashboard EventsHub receives session events even with no gRPC subscriber streaming —
|
||||
/// fixing the "dark feed" where the dashboard only saw events while a gRPC client was
|
||||
/// actively streaming. Registering the internal subscriber BEFORE
|
||||
/// <see cref="SessionEventDistributor.StartAsync"/> also avoids the Task 4 hazard where
|
||||
/// <see cref="SessionEventDistributor.StartAsync"/> also avoids the hazard where
|
||||
/// starting the pump at Ready with zero subscribers drained a fast-completing worker
|
||||
/// stream into nothing and left a later subscriber hanging: there is now always a
|
||||
/// subscriber (the dashboard one) registered before the pump starts.
|
||||
@@ -444,7 +443,7 @@ public sealed class GatewaySession
|
||||
// single drain to first-attach preserves that "events start flowing on subscribe"
|
||||
// behavior and avoids draining a fast-completing source into the void before any
|
||||
// subscriber exists. The source factory mirrors the mapping/ordering/start that
|
||||
// EventStreamService.ProduceEventsAsync used before Task 4: it drains the worker event
|
||||
// EventStreamService.ProduceEventsAsync previously used: it drains the worker event
|
||||
// stream in source order and maps each WorkerEvent to the public MxEvent with the same
|
||||
// mapper, with no skip/filter — per-RPC filtering (e.g. AfterWorkerSequence) stays at the
|
||||
// subscriber boundary in EventStreamService. Returns a registered lease atomically with
|
||||
@@ -462,7 +461,7 @@ public sealed class GatewaySession
|
||||
return lease;
|
||||
}
|
||||
|
||||
// Reconnect/resume variant of StartDistributorAndRegister (Task 12). Snapshots the replay
|
||||
// Reconnect/resume variant of StartDistributorAndRegister. Snapshots the replay
|
||||
// ring for events newer than afterSequence AND registers the live subscriber atomically
|
||||
// under the distributor's replay lock, so the replay→live handoff has no gap and no
|
||||
// duplicate (see SessionEventDistributor.RegisterWithReplay). The pump is started after
|
||||
@@ -542,7 +541,7 @@ public sealed class GatewaySession
|
||||
// once when the session becomes Ready (idempotent). The internal subscriber is registered
|
||||
// BEFORE the pump starts (see StartDistributorAndRegister / EnsureDistributorCreated), so
|
||||
// a subscriber is always present at pump start — the dashboard receives events with no
|
||||
// gRPC subscriber attached, and the Task 4 "zero-subscriber drain into the void" hang
|
||||
// gRPC subscriber attached, and the "zero-subscriber drain into the void" hang
|
||||
// cannot occur. No-op when no dashboard broadcaster was supplied (unit tests).
|
||||
//
|
||||
// Race-safety (Issue 1): _dashboardMirrorLease and _dashboardMirrorTask are published
|
||||
@@ -605,14 +604,14 @@ public sealed class GatewaySession
|
||||
}
|
||||
|
||||
// Reads the internal dashboard subscriber's channel and publishes each RAW fanned event
|
||||
// to the dashboard broadcaster. The dashboard is a first-class distributor subscriber
|
||||
// (Task 6), so it sees the session's full raw event activity — NOT the per-gRPC-subscriber
|
||||
// to the dashboard broadcaster. The dashboard is a first-class distributor subscriber,
|
||||
// so it sees the session's full raw event activity — NOT the per-gRPC-subscriber
|
||||
// AfterWorkerSequence filtering that EventStreamService applies at its own boundary. This
|
||||
// is intentional: the dashboard is a separate LDAP-authenticated monitoring view (per-
|
||||
// session dashboard ACL is the separate Task 18). Publish is best-effort / never-throw, so
|
||||
// session dashboard ACL is a separate concern). Publish is best-effort / never-throw, so
|
||||
// a slow or broken dashboard cannot fault the session or stall the pump; the bounded
|
||||
// internal subscriber channel (Task 5 per-subscriber isolation) only disconnects THIS
|
||||
// mirror on overflow, leaving the session and other subscribers untouched.
|
||||
// internal subscriber channel only disconnects THIS mirror on overflow, leaving the
|
||||
// session and other subscribers untouched.
|
||||
private async Task RunDashboardMirrorAsync(
|
||||
IDashboardEventBroadcaster broadcaster,
|
||||
IEventSubscriberLease lease,
|
||||
@@ -757,6 +756,7 @@ public sealed class GatewaySession
|
||||
/// Determines whether the session lease has expired.
|
||||
/// </summary>
|
||||
/// <param name="now">Current timestamp for comparison.</param>
|
||||
/// <returns><see langword="true"/> if the lease has expired with no active event subscriber; otherwise <see langword="false"/>.</returns>
|
||||
public bool IsLeaseExpired(DateTimeOffset now)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
@@ -778,6 +778,7 @@ public sealed class GatewaySession
|
||||
/// window).
|
||||
/// </summary>
|
||||
/// <param name="now">Current timestamp for comparison.</param>
|
||||
/// <returns><see langword="true"/> if the detach-grace window has elapsed with no re-attached subscriber; otherwise <see langword="false"/>.</returns>
|
||||
public bool IsDetachGraceExpired(DateTimeOffset now)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
@@ -813,6 +814,7 @@ public sealed class GatewaySession
|
||||
/// succeed past it. On distributor-register failure the count is rolled back (see the
|
||||
/// catch below).
|
||||
/// </remarks>
|
||||
/// <returns>A lease that reads the fanned public events for this subscriber.</returns>
|
||||
public IEventSubscriberLease AttachEventSubscriber(int maxSubscribers)
|
||||
{
|
||||
// Derive the mode from the same source the distributor uses so the two can never
|
||||
@@ -868,7 +870,7 @@ public sealed class GatewaySession
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reconnect/resume variant of <see cref="AttachEventSubscriber"/> (Task 12). Attaches
|
||||
/// Reconnect/resume variant of <see cref="AttachEventSubscriber"/>. Attaches
|
||||
/// an event subscriber AND atomically snapshots the session replay ring for events newer
|
||||
/// than <paramref name="afterSequence"/>, so a resuming client can replay what it missed
|
||||
/// before live delivery resumes — with no gap and no duplicate across the handoff.
|
||||
@@ -939,7 +941,7 @@ public sealed class GatewaySession
|
||||
|
||||
// Records that an external subscriber attached successfully. Gates the detach-grace
|
||||
// "last subscriber dropped" stamp so a FAILED first attach (which still rolls back via
|
||||
// DetachEventSubscriber) never pushes a never-subscribed session into grace (Server-055).
|
||||
// DetachEventSubscriber) never pushes a never-subscribed session into grace.
|
||||
private void MarkEventSubscriberAttached()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
@@ -953,6 +955,7 @@ public sealed class GatewaySession
|
||||
/// </summary>
|
||||
/// <param name="command">Worker command to invoke.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The worker's reply to the command.</returns>
|
||||
public async Task<WorkerCommandReply> InvokeAsync(
|
||||
WorkerCommand command,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -969,7 +972,7 @@ public sealed class GatewaySession
|
||||
return await workerClient.InvokeAsync(command, CommandTimeout, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Single outbound choke point for the two array-write ergonomics shims (Task 3):
|
||||
// Single outbound choke point for the two array-write ergonomics shims:
|
||||
// 1. AddItem/AddItem2 array addresses gain the writable "[]" suffix when Galaxy metadata
|
||||
// reports them as arrays, so the worker registers a write-capable handle. The mutation
|
||||
// lands on the same MxCommand instance forwarded to the worker.
|
||||
@@ -1063,6 +1066,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">The MXAccess server handle.</param>
|
||||
/// <param name="itemHandle">The MXAccess item handle.</param>
|
||||
/// <param name="registration">The item registration if found.</param>
|
||||
/// <returns><see langword="true"/> if a registration was found for the handle pair; otherwise <see langword="false"/>.</returns>
|
||||
public bool TryGetItemRegistration(
|
||||
int serverHandle,
|
||||
int itemHandle,
|
||||
@@ -1136,6 +1140,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="tagAddresses">Tag addresses to add.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-address subscribe results.</returns>
|
||||
public Task<IReadOnlyList<SubscribeResult>> AddItemBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<string> tagAddresses,
|
||||
@@ -1161,6 +1166,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="itemHandles">Item handles to advise.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-handle subscribe results.</returns>
|
||||
public Task<IReadOnlyList<SubscribeResult>> AdviseItemBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<int> itemHandles,
|
||||
@@ -1186,6 +1192,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="itemHandles">Item handles to remove.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-handle subscribe results.</returns>
|
||||
public Task<IReadOnlyList<SubscribeResult>> RemoveItemBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<int> itemHandles,
|
||||
@@ -1211,6 +1218,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="itemHandles">Item handles to un-advise.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-handle subscribe results.</returns>
|
||||
public Task<IReadOnlyList<SubscribeResult>> UnAdviseItemBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<int> itemHandles,
|
||||
@@ -1236,6 +1244,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="tagAddresses">Tag addresses to subscribe to.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-address subscribe results.</returns>
|
||||
public Task<IReadOnlyList<SubscribeResult>> SubscribeBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<string> tagAddresses,
|
||||
@@ -1261,6 +1270,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="itemHandles">Item handles to unsubscribe from.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-handle subscribe results.</returns>
|
||||
public Task<IReadOnlyList<SubscribeResult>> UnsubscribeBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<int> itemHandles,
|
||||
@@ -1284,6 +1294,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="entries">Write entries to execute.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-entry write results.</returns>
|
||||
public Task<IReadOnlyList<BulkWriteResult>> WriteBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<WriteBulkEntry> entries,
|
||||
@@ -1307,6 +1318,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="entries">Write entries to execute.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-entry write results.</returns>
|
||||
public Task<IReadOnlyList<BulkWriteResult>> Write2BulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<Write2BulkEntry> entries,
|
||||
@@ -1330,6 +1342,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="entries">Write entries to execute.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-entry write results.</returns>
|
||||
public Task<IReadOnlyList<BulkWriteResult>> WriteSecuredBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<WriteSecuredBulkEntry> entries,
|
||||
@@ -1353,6 +1366,7 @@ public sealed class GatewaySession
|
||||
/// <param name="serverHandle">Server handle returned by the worker.</param>
|
||||
/// <param name="entries">Write entries to execute.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-entry write results.</returns>
|
||||
public Task<IReadOnlyList<BulkWriteResult>> WriteSecured2BulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<WriteSecured2BulkEntry> entries,
|
||||
@@ -1380,6 +1394,7 @@ public sealed class GatewaySession
|
||||
/// <param name="tagAddresses">Tag addresses to read.</param>
|
||||
/// <param name="timeout">Timeout for the read operation.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The per-address read results.</returns>
|
||||
public Task<IReadOnlyList<BulkReadResult>> ReadBulkAsync(
|
||||
int serverHandle,
|
||||
IReadOnlyList<string> tagAddresses,
|
||||
@@ -1437,6 +1452,7 @@ public sealed class GatewaySession
|
||||
/// <see cref="TransitionTo"/> / <see cref="MarkFaulted"/> and a concurrent
|
||||
/// <c>TransitionTo(Ready)</c> cannot race past a <c>Closing</c> write.
|
||||
/// </remarks>
|
||||
/// <returns>The outcome of the close operation.</returns>
|
||||
public async Task<SessionCloseResult> CloseAsync(
|
||||
string reason,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -1613,7 +1629,7 @@ public sealed class GatewaySession
|
||||
/// Mirrors <see cref="CloseAsync"/>'s use of <c>_closeLock</c> so that
|
||||
/// a Close in flight from one caller and a Kill from another do not
|
||||
/// race on the "was the session already closed" observation that
|
||||
/// drives metric increments (Server-045).
|
||||
/// drives metric increments.
|
||||
/// </remarks>
|
||||
/// <param name="reason">Reason for killing the worker.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
@@ -1652,6 +1668,7 @@ public sealed class GatewaySession
|
||||
/// The acquire is best-effort: a non-cancellable wait that swallows
|
||||
/// <see cref="ObjectDisposedException"/> so double-dispose still completes.
|
||||
/// </remarks>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
try
|
||||
@@ -1991,7 +2008,7 @@ public sealed class GatewaySession
|
||||
// session instead of letting it linger only on the (long) lease: stamp the detached
|
||||
// time so the lease monitor can close it once the grace window elapses. The session
|
||||
// stays in its current (Ready) state and remains usable, so a reconnecting subscriber
|
||||
// (Task 12) re-attaches normally. The gateway-owned internal dashboard subscriber is
|
||||
// re-attaches normally. The gateway-owned internal dashboard subscriber is
|
||||
// NOT counted in _activeEventSubscriberCount (it registers on the distributor with
|
||||
// isInternal: true), so a session whose only remaining subscriber is the dashboard
|
||||
// mirror still enters grace. Only stamp while the session is alive — once
|
||||
@@ -2001,7 +2018,7 @@ public sealed class GatewaySession
|
||||
// Only stamp a detach that mirrors a prior SUCCESSFUL attach. The attach catch path
|
||||
// calls this same method to roll back a reserved slot when the FIRST attach failed
|
||||
// before any subscriber registered; that never-subscribed session must not enter the
|
||||
// grace window (Server-055).
|
||||
// grace window.
|
||||
if (_everHadEventSubscriber
|
||||
&& _detachGrace > TimeSpan.Zero
|
||||
&& _activeEventSubscriberCount == 0
|
||||
|
||||
Reference in New Issue
Block a user