perf(comms+audit): close phase-2 residuals — direct ingest path, monotonic timeouts, synthetic probe, not-reporting set, cursor-exact audit pull

This commit is contained in:
Joseph Doherty
2026-08-14 21:38:23 -04:00
parent 4cd1441984
commit a5882753dd
38 changed files with 1254 additions and 443 deletions
@@ -58,15 +58,21 @@ public class AuditLogIngestActor : ReceiveActor
/// SHORTER than the gRPC Ask that wraps it.
/// </summary>
/// <remarks>
/// The path used to stack three identical 30 s budgets — the site's Ask
/// (<c>CommunicationOptions.NotificationForwardTimeout</c>), the central gRPC
/// handler's Ask (<c>SiteStreamGrpcServer.AuditIngestAskTimeout</c>) and the
/// ADO.NET command default — so they all expired at the same instant. The
/// The path used to stack three identical 30 s budgets — the site's Ask, the
/// central gRPC handler's Ask (<c>SiteStreamGrpcServer.AuditIngestAskTimeout</c>)
/// and the ADO.NET command default — so they all expired at the same instant. The
/// caller therefore learned nothing except "it took 30 s": no partial ack, no
/// distinction between a slow database and a wedged singleton. Making the
/// innermost budget strictly smallest means a slow batch is abandoned by the
/// actor FIRST, with the accepted-so-far ids still replied, while the outer
/// Asks are still waiting.
/// <para>
/// The full ladder is now strictly monotonic end to end:
/// <c>CommunicationOptions.AuditForwardTimeout</c> (35 s, the site-side forward Ask) &gt;
/// <c>SiteStreamGrpcServer.AuditIngestAskTimeout</c> (30 s, the gRPC deadline AND central's
/// Ask of this singleton) &gt; <see cref="IngestBudget"/> (20 s) &gt;
/// <see cref="IngestSqlCommandTimeout"/> (15 s).
/// </para>
/// </remarks>
internal static readonly TimeSpan IngestBudget = TimeSpan.FromSeconds(20);