backup-scheduler: dont replay missed daily slots on startup #42
@@ -37,11 +37,28 @@ public sealed class BackupScheduler : IDisposable
|
|||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(_config.BackupSchedule)) return;
|
if (string.IsNullOrWhiteSpace(_config.BackupSchedule)) return;
|
||||||
if (Parse(_config.BackupSchedule) == default)
|
var parsed = Parse(_config.BackupSchedule);
|
||||||
|
if (parsed == default)
|
||||||
{
|
{
|
||||||
_log($"[backup-scheduler] Invalid backupSchedule '{_config.BackupSchedule}'. Expected 'HH:mm', 'HH:mm,HH:mm', or 'every Nh'/'every Nm'. Disabled.");
|
_log($"[backup-scheduler] Invalid backupSchedule '{_config.BackupSchedule}'. Expected 'HH:mm', 'HH:mm,HH:mm', or 'every Nh'/'every Nm'. Disabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No-replay startup: mark all of today's already-passed slots as fired so
|
||||||
|
// the wake loop only fires future slots. Without this, a daily-times
|
||||||
|
// schedule like "00:00,04:00,...,20:00" on a service restart at 19:00
|
||||||
|
// would catch up by firing 5 backups at 1-minute intervals (one per
|
||||||
|
// missed slot), each producing a full-world zip of the SAME world state.
|
||||||
|
// For full-snapshot backups that's pure waste -- the live world hasn't
|
||||||
|
// diverged across missed slots.
|
||||||
|
if (parsed.Times is not null)
|
||||||
|
{
|
||||||
|
var nowTime = TimeOnly.FromDateTime(DateTime.Now);
|
||||||
|
_lastFireDay = DateOnly.FromDateTime(DateTime.Now);
|
||||||
|
foreach (var t in parsed.Times)
|
||||||
|
if (t <= nowTime) _firedToday.Add(t);
|
||||||
|
}
|
||||||
|
|
||||||
_cts?.Cancel();
|
_cts?.Cancel();
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
_loop = Task.Run(() => RunAsync(_cts.Token));
|
_loop = Task.Run(() => RunAsync(_cts.Token));
|
||||||
|
|||||||
Reference in New Issue
Block a user