Same fix as AyaNova: the backup ran at the stored UTC hour, so with daylight saving it moved an hour on the server's clock for part of the year. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
86 lines
3.6 KiB
C#
86 lines
3.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Sockeye.Models;
|
|
|
|
namespace Sockeye.Util
|
|
{
|
|
|
|
/// <summary>
|
|
/// Contains static mirror copy in memory of Operations related settings stored in db
|
|
/// that are accessed frequently by server
|
|
/// </summary>
|
|
internal static class ServerGlobalOpsSettingsCache
|
|
{
|
|
//BOOT flag, set during boot and
|
|
//is used to control generator from starting
|
|
internal static bool BOOTING { get; set; }
|
|
|
|
//False if db server is detected to be down
|
|
//is used to control generator from processing
|
|
internal static bool DBAVAILABLE { get; set; }
|
|
|
|
internal static GlobalOpsBackupSettings Backup { get; set; }
|
|
internal static GlobalOpsNotificationSettings Notify { get; set; }
|
|
internal static DateTime NextBackup { get; set; }
|
|
/// <summary>
|
|
/// Populate and / or create the settings
|
|
/// </summary>
|
|
internal static void Initialize(AyContext ct = null)
|
|
{
|
|
//fetch or create as not provided (meaning this was called from Startup.cs)
|
|
Backup = ct.GlobalOpsBackupSettings.FirstOrDefault(z => z.Id == 1);
|
|
if (Backup == null)
|
|
{
|
|
Backup = new GlobalOpsBackupSettings();
|
|
ct.GlobalOpsBackupSettings.Add(Backup);
|
|
ct.SaveChanges();
|
|
}
|
|
NextBackup = FileUtil.MostRecentAutomatedBackupFileDate();
|
|
SetNextBackup();
|
|
|
|
|
|
Notify = ct.GlobalOpsNotificationSettings.FirstOrDefault(z => z.Id == 1);
|
|
if (Notify == null)
|
|
{
|
|
Notify = new GlobalOpsNotificationSettings();
|
|
ct.GlobalOpsNotificationSettings.Add(Notify);
|
|
ct.SaveChanges();
|
|
}
|
|
}
|
|
|
|
internal static void SetNextBackup()
|
|
{
|
|
DateTime utcNow = DateTime.UtcNow;
|
|
//case 4682: the backup time is a time on the server's clock; days are the server's local days
|
|
DateTime localToday = TimeZoneInfo.ConvertTimeFromUtc(utcNow, TimeZoneInfo.Local).Date;
|
|
//Has last backup run more than 24 hours ago?
|
|
if (NextBackup < utcNow.AddHours(-24))
|
|
{
|
|
//set it to today then
|
|
NextBackup = BackupTimeOnLocalDay(localToday);
|
|
//Make sure next backup is in the future
|
|
if (NextBackup < utcNow)
|
|
NextBackup = BackupTimeOnLocalDay(localToday.AddDays(1));
|
|
}
|
|
else
|
|
{
|
|
//less than 24 hours, set it to tomorrow
|
|
NextBackup = BackupTimeOnLocalDay(localToday.AddDays(1));
|
|
}
|
|
}
|
|
|
|
//case 4682: the backup time is stored as the UTC moment it meant on the day it was set, and was run at that UTC hour
|
|
//every day, so it moved an hour on the server's clock with each daylight saving change. The server's clock time is
|
|
//recovered with that day's offset and the backup is run at that clock time on the given local day (UTC returned)
|
|
private static DateTime BackupTimeOnLocalDay(DateTime localDay)
|
|
{
|
|
var chosen = TimeZoneInfo.ConvertTimeFromUtc(DateTime.SpecifyKind(Backup.BackupTime, DateTimeKind.Utc), TimeZoneInfo.Local);
|
|
var local = DateTime.SpecifyKind(localDay.Date + new TimeSpan(chosen.Hour, chosen.Minute, 0), DateTimeKind.Unspecified);
|
|
//a time skipped when the clocks go forward (e.g. 2:30 AM that night) runs an hour later
|
|
if (TimeZoneInfo.Local.IsInvalidTime(local))
|
|
local = local.AddHours(1);
|
|
return TimeZoneInfo.ConvertTimeToUtc(local, TimeZoneInfo.Local);
|
|
}
|
|
|
|
}//eoc
|
|
}//eons |