docs(src): fix CommentChecker findings across src/ — 1,032 → 5 (all false positives)
Comment/XML-doc changes only, no code logic: - strip project-tracking references (WP*, P*-*, row-NN, #NN, Task N) from comments, keeping the explanatory rationale - add missing summaries, <param>, <returns>, <typeparam> and <inheritdoc/> - replace misused <inheritdoc/> with real docs; where <inheritdoc/> was combined with useful remarks, move the rationale into // comments - drop stale replicationActor <param> on DeploymentManagerActor ctor Remaining 5 are false positives (CWE-1236 x2, failures-1, year-0001, M365). Build 0 errors / 0 warnings.
This commit is contained in:
@@ -227,7 +227,7 @@ public class AuditLogIngestActor : ReceiveActor
|
||||
projected.Add(AuditRowProjection.WithIngestedAtUtc(filtered, nowUtc));
|
||||
}
|
||||
|
||||
// ONE set-based statement for the whole packet (WP2.2) instead of one
|
||||
// ONE set-based statement for the whole packet instead of one
|
||||
// IF NOT EXISTS … INSERT round trip per event. A telemetry packet of 200
|
||||
// rows used to cost 200 sequential round trips on the central singleton's
|
||||
// dispatcher; it now costs two. Idempotency is unchanged — duplicates
|
||||
@@ -356,7 +356,7 @@ public class AuditLogIngestActor : ReceiveActor
|
||||
|
||||
var strategy = dbContext.Database.CreateExecutionStrategy();
|
||||
|
||||
// Fast path (WP2.2): the WHOLE packet in ONE transaction — one
|
||||
// Fast path: the WHOLE packet in ONE transaction — one
|
||||
// set-based audit insert plus one single-statement upsert per entry.
|
||||
// The predecessor opened a transaction PER entry and issued three
|
||||
// statements inside it (IF NOT EXISTS insert, then the two-statement
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
|
||||
/// than <c>DateTime.UtcNow - RetentionDays</c>.</item>
|
||||
/// <item>For each eligible boundary, calls
|
||||
/// <see cref="IAuditLogRepository.SwitchOutPartitionAsync"/>, a
|
||||
/// metadata-only staging-table switch (WP2.2 removed the index
|
||||
/// drop/rebuild that used to bracket it).</item>
|
||||
/// metadata-only staging-table switch (no index
|
||||
/// drop/rebuild brackets it).</item>
|
||||
/// <item>Publishes <see cref="AuditLogPurgedEvent"/> on the actor-system
|
||||
/// EventStream so the central health collector + ops surfaces
|
||||
/// can subscribe without coupling to this actor.</item>
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The purge actor is a daily-cadence singleton, not a hot-loop. The
|
||||
/// partition switch itself is metadata-only (since WP2.2's
|
||||
/// <c>AlignAuditLogEventIdUniqueness</c> it no longer drops and rebuilds a
|
||||
/// partition switch itself is metadata-only (since the
|
||||
/// <c>AlignAuditLogEventIdUniqueness</c> migration it no longer drops and rebuilds a
|
||||
/// non-aligned unique index around it), but it still takes schema-modification
|
||||
/// locks and competes with ingest for the same table. Lower this only when an
|
||||
/// operator can prove they need sub-daily purge granularity.
|
||||
|
||||
@@ -28,6 +28,9 @@ public sealed class GrpcPullTraceEventsClient : IPullTraceEventsClient
|
||||
private readonly ILogger<GrpcPullTraceEventsClient> _logger;
|
||||
|
||||
/// <summary>Creates the client over the given site enumerator and unary-call invoker.</summary>
|
||||
/// <param name="sites">Enumerates the sites and their gRPC endpoints.</param>
|
||||
/// <param name="invoker">Issues the unary <c>PullTraceEvents</c> call.</param>
|
||||
/// <param name="logger">Logger for pull diagnostics.</param>
|
||||
public GrpcPullTraceEventsClient(
|
||||
ISiteEnumerator sites,
|
||||
IPullTraceEventsInvoker invoker,
|
||||
@@ -152,6 +155,11 @@ public sealed class GrpcPullTraceEventsClient : IPullTraceEventsClient
|
||||
public interface IPullTraceEventsInvoker
|
||||
{
|
||||
/// <summary>Issues the RPC against <paramref name="endpoint"/> with the site's preshared key.</summary>
|
||||
/// <param name="siteId">The site the call targets.</param>
|
||||
/// <param name="endpoint">The site node gRPC endpoint to call.</param>
|
||||
/// <param name="request">The pull request.</param>
|
||||
/// <param name="ct">Token to cancel the call.</param>
|
||||
/// <returns>The site's trace-event response.</returns>
|
||||
Task<PullTraceEventsResponse> InvokeAsync(
|
||||
string siteId, string endpoint, PullTraceEventsRequest request, CancellationToken ct);
|
||||
}
|
||||
@@ -169,6 +177,8 @@ public sealed class GrpcPullTraceEventsInvoker : GrpcPullTraceEventsClient.IPull
|
||||
private readonly ISitePskProvider? _pskProvider;
|
||||
|
||||
/// <summary>Creates the invoker with the given options and optional per-site PSK provider.</summary>
|
||||
/// <param name="options">Communication options supplying keepalive settings.</param>
|
||||
/// <param name="pskProvider">Optional provider of per-site preshared keys.</param>
|
||||
public GrpcPullTraceEventsInvoker(CommunicationOptions options, ISitePskProvider? pskProvider)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
@@ -212,7 +222,7 @@ public sealed class GrpcPullTraceEventsInvoker : GrpcPullTraceEventsClient.IPull
|
||||
},
|
||||
}.WithMessageLimits().WithSiteCredentials(_pskProvider, siteId));
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Disposes every cached gRPC channel.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var channel in _channels.Values)
|
||||
|
||||
@@ -521,6 +521,8 @@ public class SiteAuditReconciliationActor : ReceiveActor
|
||||
/// lost rows get distinct synthetic ids.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="lostEventId">The event id of the lost row being abandoned.</param>
|
||||
/// <returns>A deterministic synthetic GUID for the abandonment row.</returns>
|
||||
internal static Guid DeriveAbandonmentEventId(Guid lostEventId)
|
||||
{
|
||||
Span<byte> input = stackalloc byte[32];
|
||||
|
||||
@@ -150,7 +150,7 @@ public sealed class ScadaBridgeAuditRedactor : IAuditRedactor, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Disposes the options-change registration, if any.</summary>
|
||||
public void Dispose() => _optionsReload?.Dispose();
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -174,7 +174,7 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
|
||||
pragmaCmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// synchronous=NORMAL (arch-review remediation WP1.2): SQLite's FULL default
|
||||
// synchronous=NORMAL: SQLite's FULL default
|
||||
// fsyncs on every transaction commit, which is the dominant cost of the
|
||||
// per-event write path this same change coalesces via FlushIntervalMs — FULL
|
||||
// would still fsync once per FLUSH even after that fix. NORMAL fsyncs at
|
||||
@@ -346,8 +346,8 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
|
||||
// burst of concurrent enqueues. Once the immediately-available
|
||||
// burst is drained, keep the transaction open for up to
|
||||
// FlushIntervalMs waiting for MORE events to trickle in — this is
|
||||
// the soft-flush coalescing arch-review remediation WP1.2 adds:
|
||||
// without it, a low-rate trickle of writes (one script call every
|
||||
// the soft-flush coalescing
|
||||
// this loop provides: without it, a low-rate trickle of writes (one script call every
|
||||
// few ms, well under BatchSize) fsyncs once PER EVENT, because the
|
||||
// writer loop reaches an empty channel and flushes immediately.
|
||||
// FlushIntervalMs bounds the worst-case added latency any single
|
||||
@@ -392,8 +392,7 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
|
||||
|
||||
/// <summary>
|
||||
/// Total number of <see cref="FlushBatch"/> transactions committed since
|
||||
/// construction. Test-only observability seam (arch-review remediation
|
||||
/// WP1.2) for asserting that FlushIntervalMs coalesces a trickle of
|
||||
/// construction. Test-only observability seam for asserting that FlushIntervalMs coalesces a trickle of
|
||||
/// near-simultaneous writes into a single transaction rather than one
|
||||
/// commit per event; production code never reads this.
|
||||
/// </summary>
|
||||
@@ -499,8 +498,7 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
|
||||
{
|
||||
eventCmd.ExecuteNonQuery();
|
||||
fwdCmd.ExecuteNonQuery();
|
||||
// Do NOT complete pending.Completion here (arch-review 2026-08-19
|
||||
// P4-2). A row's INSERTs succeeding is not durable until the
|
||||
// Do NOT complete pending.Completion here. A row's INSERTs succeeding is not durable until the
|
||||
// transaction actually commits below — completing the caller's Task
|
||||
// this early means a later commit failure (SQLITE_FULL, IOERR, or a
|
||||
// later row in this same batch throwing) reports false success: the
|
||||
@@ -866,7 +864,15 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
|
||||
/// <summary>Flow Debugger PullTraceEvents: hard cap on ids per read (design §5.4).</summary>
|
||||
public const int MaxExecutionIdsPerRead = 64;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Reads audit events belonging to any of the given execution ids, newer than <paramref name="sinceUtc"/>, in keyset-paged order.
|
||||
/// </summary>
|
||||
/// <param name="executionIds">Execution ids to match (capped at <see cref="MaxExecutionIdsPerRead"/>).</param>
|
||||
/// <param name="sinceUtc">Lower bound on the event's occurrence time.</param>
|
||||
/// <param name="limit">Maximum number of events to return; must be positive.</param>
|
||||
/// <param name="ct">Cancellation token.</param>
|
||||
/// <param name="afterEventId">Optional keyset cursor; only events after this id are returned.</param>
|
||||
/// <returns>The matching audit events.</returns>
|
||||
public Task<IReadOnlyList<AuditEvent>> ReadByExecutionIdsAsync(
|
||||
IReadOnlyCollection<Guid> executionIds, DateTime sinceUtc, int limit, CancellationToken ct = default, string? afterEventId = null)
|
||||
{
|
||||
@@ -925,6 +931,8 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
|
||||
/// UNION deduplicates rows matching both IDs. Keeping payloads outside the union bounds sorting
|
||||
/// to IDs/timestamps and avoids the optimizer preferring a whole-store timestamp scan.
|
||||
/// </summary>
|
||||
/// <param name="inList">The pre-built SQL parameter list for the <c>IN (...)</c> clauses.</param>
|
||||
/// <returns>The trace-read SQL text.</returns>
|
||||
internal static string BuildTraceReadSql(string inList) => $"""
|
||||
SELECT e.EventId, e.OccurredAtUtc, e.Actor, e.Action, e.Outcome,
|
||||
e.Category, e.Target, e.SourceNode, e.CorrelationId, e.DetailsJson
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see cref="SqliteAuditWriterOptions.DatabasePath"/> is deliberately NOT
|
||||
/// validated here (arch-review remediation WP1.2). <c>AddAuditLog</c> runs on
|
||||
/// validated here. <c>AddAuditLog</c> runs on
|
||||
/// BOTH Central and Site composition roots and binds this options type with
|
||||
/// <c>ValidateOnStart</c> either way, but only Site nodes ever resolve
|
||||
/// <see cref="SqliteAuditWriter"/> — requiring a non-empty path in this
|
||||
|
||||
@@ -17,6 +17,8 @@ internal static class SqliteErrorCodes
|
||||
/// "primary/extended" (e.g. "10/522") for a <see cref="SqliteException"/>
|
||||
/// anywhere in the exception chain; "n/a" for non-SQLite failures.
|
||||
/// </summary>
|
||||
/// <param name="ex">The exception to inspect, including its inner exceptions.</param>
|
||||
/// <returns>The "primary/extended" SQLite error code string, or "n/a" for non-SQLite failures.</returns>
|
||||
public static string Describe(Exception ex)
|
||||
{
|
||||
for (Exception? e = ex; e is not null; e = e.InnerException)
|
||||
|
||||
Reference in New Issue
Block a user