-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathClearOldShockerControlLogs.cs
More file actions
70 lines (60 loc) · 2.63 KB
/
ClearOldShockerControlLogs.cs
File metadata and controls
70 lines (60 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using Microsoft.EntityFrameworkCore;
using OpenShock.Common;
using OpenShock.Common.Constants;
using OpenShock.Common.OpenShockDb;
using OpenShock.Cron.Attributes;
namespace OpenShock.Cron.Jobs;
/// <summary>
/// Deletes shocker control logs older than the retention period and enforces a maximum log count
/// </summary>
[CronJob("0 0 * * *")] // Every day at midnight (https://crontab.guru/)
public sealed class ClearOldShockerControlLogs
{
private readonly OpenShockContext _db;
private readonly ILogger<ClearOldShockerControlLogs> _logger;
/// <summary>
/// DI constructor
/// </summary>
/// <param name="db"></param>
/// <param name="logger"></param>
public ClearOldShockerControlLogs(OpenShockContext db, ILogger<ClearOldShockerControlLogs> logger)
{
_db = db;
_logger = logger;
}
public async Task Execute()
{
// Calculate the retention threshold based on configured retention time.
var retentionThreshold = DateTime.UtcNow - Duration.ShockerControlLogRetentionTime;
// Delete logs older than the retention threshold.
var deletedByAge = await _db.ShockerControlLogs
.Where(log => log.CreatedOn < retentionThreshold)
.ExecuteDeleteAsync();
_logger.LogInformation("Deleted {deletedCount} shocker control logs older than {retentionThreshold:O}.", deletedByAge, retentionThreshold);
var userLogsCounts = await _db.ShockerControlLogs
.GroupBy(log => log.Shocker.DeviceNavigation.Owner)
.Select(group => new
{
UserId = group.Key,
CountToDelete = Math.Max(0, group.Count() - HardLimits.MaxShockerControlLogsPerUser),
DeleteBeforeDate = group
.OrderByDescending(log => log.CreatedOn)
.Skip(HardLimits.MaxShockerControlLogsPerUser)
.Select(log => log.CreatedOn)
.FirstOrDefault()
})
.Where(result => result.CountToDelete > 0)
.ToArrayAsync();
if (userLogsCounts.Length != 0)
{
_logger.LogInformation("A total of {totalLogsToDelete} logs will be deleted to enforce per-user limits.", userLogsCounts.Sum(x => x.CountToDelete));
foreach (var userLogCount in userLogsCounts)
{
await _db.ShockerControlLogs
.Where(log => log.Shocker.DeviceNavigation.Owner == userLogCount.UserId && log.CreatedOn < userLogCount.DeleteBeforeDate)
.ExecuteDeleteAsync();
}
}
_logger.LogInformation("Done!");
}
}