.NET API
IRetentionStore
Tracon.Abstractions.dllThe data plane that counts, batch-deletes, and reads-for-archive over the actual retention data.
public interface IRetentionStoreRemarks
Section titled “Remarks”The target name parameter always comes from the RetentionTargets allowlist; implementations must throw ArgumentException for an unknown target.
Which column counts as “age” and which extra condition (for example, only completed jobs) applies is fixed for EACH target and stays embedded inside the implementation; the caller knows only the target name and the cutoff date.
Tenant scoping is mandatory. A retention
policy is defined per tenant; if tenantId is not given, the
operation touches every tenant’s rows. Only the installation-wide
('*') policy should pass null.
The default (in-memory) setup registers NullRetentionStore, which
always returns empty/zero: retention is meaningful only when a SQL
provider is enabled.
DI lifetime — singleton. Registered as a singleton with
TryAdd; a consumer’s own registration wins.
Methods
Section titled “Methods”ArchiveBatchAsync(string, string?, DateTimeOffset, int, Func<IReadOnlyList<ArchiveRow>, CancellationToken, ValueTask>, CancellationToken)
Section titled “ ArchiveBatchAsync(string, string?, DateTimeOffset, int, Func<IReadOnlyList<ArchiveRow>, CancellationToken, ValueTask>, CancellationToken)”Reads one batch of rows older than the cutoff date, hands it to
archiveAsync, and then deletes exactly the rows of that batch.
ValueTask<int> ArchiveBatchAsync(string target, string? tenantId, DateTimeOffset cutoff, int batchSize, Func<IReadOnlyList<ArchiveRow>, CancellationToken, ValueTask> archiveAsync, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”target string
The target name.
tenantId string?
Only this tenant’s rows; if null, runs installation-wide
(the '*' policy).
cutoff DateTimeOffset
The cutoff date (UTC).
batchSize int
The maximum number of rows to archive and delete.
archiveAsync Func<IReadOnlyList<ArchiveRow>, CancellationToken, ValueTask>
Writes the batch to the archive. It is not called when no row matches. When it throws, no row is deleted and the exception propagates.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”The number of rows deleted. It is never more than the number of rows
handed to archiveAsync; zero when no row matched.
Remarks
Section titled “Remarks”This is the archive mode of a retention run: a row that was not handed to
archiveAsync is never deleted. A row that stops matching
between the read and the delete is kept. It is archived again when it
matches on a later run, so an IArchiveSink can receive the
same row more than once.
For RetentionTargets.Attachments with an IAttachmentStorage registered, the external content of each archived row is deleted BEFORE the row, the same as in IRetentionStore.DeleteBatchAsync; a row whose content delete fails is kept.
The default implementation calls IRetentionStore.ReadForArchiveAsync and then
IRetentionStore.DeleteBatchAsync with the number of rows read. It is not EXACT:
the two calls can select different rows, and a row that was never archived
can be deleted. It exists only so a store written before this member keeps
compiling. The SQL stores override it; the shipped
RetentionStoreContract checks the rule above.
CountOlderThanAsync(string, string?, DateTimeOffset, CancellationToken)
Section titled “ CountOlderThanAsync(string, string?, DateTimeOffset, CancellationToken)”Returns the number of rows in the target currently older than the cutoff date.
ValueTask<long> CountOlderThanAsync(string target, string? tenantId, DateTimeOffset cutoff, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”target string
The target name.
tenantId string?
Only this tenant’s rows; if null, runs installation-wide
(the '*' policy).
cutoff DateTimeOffset
The cutoff date (UTC). Rows older than this match.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”The number of matching rows.
DeleteBatchAsync(string, string?, DateTimeOffset, int, CancellationToken)
Section titled “ DeleteBatchAsync(string, string?, DateTimeOffset, int, CancellationToken)”Deletes a batch of rows older than the cutoff date. This is not a
single bulk DELETE; it runs batch by batch, depending on the provider.
ValueTask<int> DeleteBatchAsync(string target, string? tenantId, DateTimeOffset cutoff, int batchSize, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”target string
The target name.
tenantId string?
Only this tenant’s rows; if null, runs installation-wide
(the '*' policy).
cutoff DateTimeOffset
The cutoff date (UTC).
batchSize int
The maximum number of rows to delete.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”The number of rows deleted. Zero means no matching row could be deleted: usually none remain, but see the remarks.
Remarks
Section titled “Remarks”For RetentionTargets.Attachments with an
IAttachmentStorage registered, each row’s external content is
deleted BEFORE the row. A row whose content delete fails is kept and still
matches, so a batch can return fewer rows than
batchSize while matching rows remain. The next run
tries the kept row again.
The batch has no order, so this method is for a run that does not archive. A run that archives uses IRetentionStore.ArchiveBatchAsync.
FindRowLimitCutoffAsync(string, string?, long, CancellationToken)
Section titled “ FindRowLimitCutoffAsync(string, string?, long, CancellationToken)”Counting from newest, returns the ordering column’s value at row
maxRows
as the cutoff date.
ValueTask<DateTimeOffset?> FindRowLimitCutoffAsync(string target, string? tenantId, long maxRows, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”target string
The target name.
tenantId string?
Only this tenant’s rows; if null, runs installation-wide (the
'*' policy).
maxRows long
The maximum number of rows to keep (at least 1).
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”The cutoff date; null if the target holds FEWER than
maxRows
rows (the volume limit is not exceeded).
Remarks
Section titled “Remarks”The returned value can be passed directly into this interface’s other three
methods (the @cutoff parameter): volume-based trimming uses the SAME
batch mechanism as age-based deletion.
ReadForArchiveAsync(string, string?, DateTimeOffset, int, CancellationToken)
Section titled “ ReadForArchiveAsync(string, string?, DateTimeOffset, int, CancellationToken)”Reads a batch of rows older than the cutoff date (does not delete).
ValueTask<IReadOnlyList<ArchiveRow>> ReadForArchiveAsync(string target, string? tenantId, DateTimeOffset cutoff, int batchSize, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”target string
The target name.
tenantId string?
Only this tenant’s rows; if null, runs installation-wide
(the '*' policy).
cutoff DateTimeOffset
The cutoff date (UTC).
batchSize int
The maximum number of rows to read.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<IReadOnlyList<ArchiveRow>>
The rows read; an empty list once no matching rows remain.
Remarks
Section titled “Remarks”The rows come in the target’s time order. IRetentionStore.DeleteBatchAsync deletes in no order, so the two calls can select different rows: archive and delete a batch with IRetentionStore.ArchiveBatchAsync instead.