feat(site-call-audit): additive (UpdatedAtUtc, TrackedOperationId) keyset in the reconciliation pull contract
Site side: additive proto after_id field, ReadChangedSinceAsync gains an optional afterId cursor and deterministic (UpdatedAtUtc, TrackedOperationId) ordering — a batch fully inside one UpdatedAtUtc instant no longer re-reads the same page forever. Absent/empty afterId preserves the exact legacy inclusive >= contract, so an older central is unaffected. Regenerated the checked-in gRPC C#.
This commit is contained in:
@@ -137,6 +137,19 @@ public interface IOperationTrackingStore
|
||||
/// the caller advance the cursor monotonically across follow-up pulls.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Composite keyset (Task 15).</b> When <paramref name="afterId"/> is
|
||||
/// supplied the read uses a <c>(UpdatedAtUtc, TrackedOperationId)</c> keyset:
|
||||
/// it returns rows strictly after that cursor — <c>UpdatedAtUtc > sinceUtc</c>,
|
||||
/// or <c>UpdatedAtUtc = sinceUtc</c> with a <c>TrackedOperationId</c> greater
|
||||
/// than <paramref name="afterId"/>. This un-pins a batch that would otherwise
|
||||
/// stall: when more than <paramref name="batchSize"/> rows share one
|
||||
/// <c>UpdatedAtUtc</c>, the plain inclusive <c>>=</c> resume re-reads the
|
||||
/// same page forever. When <paramref name="afterId"/> is <c>null</c>/empty the
|
||||
/// legacy inclusive <c>>=</c> contract is preserved exactly (an older
|
||||
/// central that does not send the cursor is unaffected). Ordering is always
|
||||
/// deterministic — <c>UpdatedAtUtc ASC, TrackedOperationId ASC</c>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <see cref="SiteCallOperational.SourceSite"/> is left as the empty string:
|
||||
/// the site id is not a tracking-store column, and the central client re-stamps
|
||||
/// it from the <c>siteId</c> it dialed (the only authority that knows which
|
||||
@@ -148,10 +161,17 @@ public interface IOperationTrackingStore
|
||||
/// </remarks>
|
||||
/// <param name="sinceUtc">Inclusive lower bound on <c>UpdatedAtUtc</c>; <see cref="DateTime.MinValue"/> reads from the start.</param>
|
||||
/// <param name="batchSize">Maximum number of rows to return (oldest first).</param>
|
||||
/// <param name="afterId">
|
||||
/// Optional composite-keyset cursor — the <c>TrackedOperationId</c> of the last
|
||||
/// row already consumed at <paramref name="sinceUtc"/>. When supplied the read
|
||||
/// returns only rows strictly after <c>(sinceUtc, afterId)</c>; when
|
||||
/// <c>null</c>/empty the legacy inclusive <c>>= sinceUtc</c> behaviour applies.
|
||||
/// </param>
|
||||
/// <param name="ct">Cancellation token.</param>
|
||||
/// <returns>The matching rows projected to <see cref="SiteCallOperational"/>, oldest-first, capped at <paramref name="batchSize"/>.</returns>
|
||||
Task<IReadOnlyList<SiteCallOperational>> ReadChangedSinceAsync(
|
||||
DateTime sinceUtc,
|
||||
int batchSize,
|
||||
string? afterId = null,
|
||||
CancellationToken ct = default);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user