feat: add thread-safe ActivityLog with bounded capacity
This commit is contained in:
48
src/SpamGuard/Services/ActivityLog.cs
Normal file
48
src/SpamGuard/Services/ActivityLog.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace SpamGuard.Services;
|
||||
|
||||
using SpamGuard.Models;
|
||||
|
||||
public sealed class ActivityLog
|
||||
{
|
||||
private readonly List<ActivityEntry> _entries = new();
|
||||
private readonly object _lock = new();
|
||||
private readonly int _maxEntries;
|
||||
|
||||
public int TodayChecked => GetTodayCount(_ => true);
|
||||
public int TodaySpam => GetTodayCount(e => e.Verdict == Verdict.Spam);
|
||||
|
||||
public ActivityLog(int maxEntries = 500)
|
||||
{
|
||||
_maxEntries = maxEntries;
|
||||
}
|
||||
|
||||
public void Add(ActivityEntry entry)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_entries.Add(entry);
|
||||
if (_entries.Count > _maxEntries)
|
||||
_entries.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ActivityEntry> GetRecent(int count = 100)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _entries
|
||||
.OrderByDescending(e => e.Timestamp)
|
||||
.Take(count)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetTodayCount(Func<ActivityEntry, bool> predicate)
|
||||
{
|
||||
var today = DateTime.UtcNow.Date;
|
||||
lock (_lock)
|
||||
{
|
||||
return _entries.Count(e => e.Timestamp.Date == today && predicate(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user