fix(sitecallaudit): time-sliced terminal purge replaces the single year-scale DELETE (plan R2-04 T11)
This commit is contained in:
+23
-3
@@ -246,9 +246,29 @@ OPTION (RECOMPILE);";
|
||||
/// <inheritdoc />
|
||||
public async Task<int> PurgeTerminalAsync(DateTime olderThanUtc, CancellationToken ct = default)
|
||||
{
|
||||
return await _context.Database.ExecuteSqlInterpolatedAsync(
|
||||
$"DELETE FROM dbo.SiteCalls WHERE TerminalAtUtc IS NOT NULL AND TerminalAtUtc < {olderThanUtc};",
|
||||
ct);
|
||||
// Time-sliced batches (arch-review 04 round 2, R6 — the one maintenance DELETE
|
||||
// that missed round 1's batching pass): each DELETE covers at most one DAY of
|
||||
// terminal rows, capping the lock/log footprint per statement. Steady state
|
||||
// (daily purge, 365-day retention) is a single slice; only catch-up after an
|
||||
// outage runs several. One-day (not one-hour) slices are proportionate to
|
||||
// SiteCalls volume, which is far below KpiSample's. The MIN() anchor and the
|
||||
// DELETE predicate both seek IX_SiteCalls_Terminal (filtered IS NOT NULL).
|
||||
var total = 0;
|
||||
var floor = await _context.SiteCalls
|
||||
.Where(s => s.TerminalAtUtc != null && s.TerminalAtUtc < olderThanUtc)
|
||||
.MinAsync(s => s.TerminalAtUtc, ct);
|
||||
while (floor is not null && floor < olderThanUtc)
|
||||
{
|
||||
var ceiling = floor.Value.AddDays(1) < olderThanUtc ? floor.Value.AddDays(1) : olderThanUtc;
|
||||
total += await _context.Database.ExecuteSqlInterpolatedAsync(
|
||||
$"DELETE FROM dbo.SiteCalls WHERE TerminalAtUtc IS NOT NULL AND TerminalAtUtc < {ceiling};",
|
||||
ct);
|
||||
floor = await _context.SiteCalls
|
||||
.Where(s => s.TerminalAtUtc != null && s.TerminalAtUtc < olderThanUtc)
|
||||
.MinAsync(s => s.TerminalAtUtc, ct);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
// Terminal status string literals for the interval-throughput KPIs. The
|
||||
|
||||
Reference in New Issue
Block a user