feat(audit-log): SiteAuditRetentionOptions (7-day default, clamped 1-90)
RetentionDays clamped [1,90]; PurgeInterval clamped to >= 1 min (Timer spin footgun); 5-min InitialDelay so a daily-recycled node still purges. (PLAN-04 Task 2)
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration for the site-side SQLite retention purge (PLAN-04 Task 2, S1/U2).
|
||||
/// The site audit store is ephemeral (~7-day retention); <see cref="SiteAuditRetentionService"/>
|
||||
/// runs <see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services.ISiteAuditQueue.PurgeExpiredAsync"/>
|
||||
/// on a timer using these knobs. Mirrors the resolve/clamp shape of
|
||||
/// <c>SiteCallAuditOptions</c> so a misconfigured value can never make the timer spin
|
||||
/// or the retention window collapse.
|
||||
/// </summary>
|
||||
public class SiteAuditRetentionOptions
|
||||
{
|
||||
/// <summary>Configuration section path bound in the site host.</summary>
|
||||
public const string SectionName = "ScadaBridge:AuditLog:SiteRetention";
|
||||
|
||||
/// <summary>
|
||||
/// Retention window in days. On each purge tick, Forwarded/Reconciled rows whose
|
||||
/// <c>OccurredAtUtc</c> is older than <c>UtcNow - ResolvedRetentionDays</c> are
|
||||
/// deleted (Pending rows are never purged on age alone). Default 7. Resolved value
|
||||
/// is clamped to <see cref="MinRetentionDays"/>..<see cref="MaxRetentionDays"/>.
|
||||
/// </summary>
|
||||
public int RetentionDays { get; set; } = 7;
|
||||
|
||||
private const int MinRetentionDays = 1;
|
||||
private const int MaxRetentionDays = 90;
|
||||
|
||||
/// <summary>
|
||||
/// Effective retention window: <see cref="RetentionDays"/> clamped to
|
||||
/// [<see cref="MinRetentionDays"/>, <see cref="MaxRetentionDays"/>] so a
|
||||
/// misconfigured 0 (which would purge everything) or an unbounded value can
|
||||
/// never take effect.
|
||||
/// </summary>
|
||||
public int ResolvedRetentionDays =>
|
||||
RetentionDays < MinRetentionDays ? MinRetentionDays
|
||||
: RetentionDays > MaxRetentionDays ? MaxRetentionDays
|
||||
: RetentionDays;
|
||||
|
||||
/// <summary>
|
||||
/// Period of the purge tick. Default 24 hours. Resolved value is clamped to at
|
||||
/// least <see cref="MinPurgeInterval"/> so a zero/negative config value cannot
|
||||
/// make the timer fire in a tight loop.
|
||||
/// </summary>
|
||||
public TimeSpan PurgeInterval { get; set; } = TimeSpan.FromHours(24);
|
||||
|
||||
private static readonly TimeSpan MinPurgeInterval = TimeSpan.FromMinutes(1);
|
||||
|
||||
/// <summary>
|
||||
/// Effective purge period: <see cref="PurgeInterval"/> clamped to at least
|
||||
/// <see cref="MinPurgeInterval"/> (the Timer/Akka zero-interval spin footgun).
|
||||
/// </summary>
|
||||
public TimeSpan ResolvedPurgeInterval =>
|
||||
PurgeInterval < MinPurgeInterval ? MinPurgeInterval : PurgeInterval;
|
||||
|
||||
/// <summary>
|
||||
/// Delay before the first purge tick. Default 5 minutes — short so a node that
|
||||
/// restarts daily (or more often) still runs the purge shortly after start
|
||||
/// rather than waiting a full <see cref="PurgeInterval"/> it may never reach.
|
||||
/// </summary>
|
||||
public TimeSpan InitialDelay { get; set; } = TimeSpan.FromMinutes(5);
|
||||
}
|
||||
Reference in New Issue
Block a user