perf(sitelog): batched event-log commits and sliced retention purge

This commit is contained in:
Joseph Doherty
2026-08-14 19:54:58 -04:00
parent ee193cd2bb
commit 2cfcd89052
4 changed files with 358 additions and 41 deletions
@@ -106,6 +106,40 @@ public class EventLogPurgeServiceTests : IDisposable
Assert.Equal(3, GetEventCount());
}
[Fact]
public void PurgeByRetention_OverBatchSize_DeletesAllExpiredRowsAcrossSlices()
{
// WP1.7: the retention purge must slice a large expired backlog into
// bounded DELETE batches (1000 rows/iteration, mirroring the storage-cap
// purge a few lines below in the same file) rather than one unbounded
// DELETE. Seed more than one slice's worth of expired rows plus a
// handful of recent rows, and assert the whole expired set is gone —
// not just the first 1000 rows — while the recent rows survive.
const int expiredCount = 2500; // > one 1000-row slice, not an exact multiple
var expiredBase = DateTimeOffset.UtcNow.AddDays(-31);
_eventLogger.WithConnection(connection =>
{
for (var i = 0; i < expiredCount; i++)
{
using var cmd = connection.CreateCommand();
cmd.CommandText = """
INSERT INTO site_events (id, timestamp, event_type, severity, source, message)
VALUES ($id, $ts, 'script', 'Info', 'Test', 'Test message')
""";
cmd.Parameters.AddWithValue("$id", Guid.NewGuid().ToString("N"));
cmd.Parameters.AddWithValue("$ts", expiredBase.AddSeconds(i).ToString("o"));
cmd.ExecuteNonQuery();
}
});
InsertEventWithTimestamp(DateTimeOffset.UtcNow.AddDays(-1));
InsertEventWithTimestamp(DateTimeOffset.UtcNow);
var purge = CreatePurgeService();
purge.RunPurge();
Assert.Equal(2, GetEventCount());
}
[Fact]
public void PurgeByStorageCap_DeletesOldestWhenOverCap()
{