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 on servers with daylight saving it ran an hour off the chosen time for part of the year. SetNextBackup now recovers the clock time with the stored date's offset and runs it on the server's local days. No migration. Backup manual page and changelog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
98 lines
4.2 KiB
C#
98 lines
4.2 KiB
C#
using System;
|
|
using System.Linq;
|
|
using AyaNova.Models;
|
|
|
|
namespace AyaNova.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; }
|
|
|
|
|
|
//VERSION CHECKING
|
|
//set by CoreJobVersionCheck once daily and kept here statically while server is up
|
|
internal static string LATEST_VERSION { get; set; }
|
|
internal static string CHANGE_LOG_URL { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
/// Populate and / or create the settings
|
|
/// </summary>
|
|
internal static void Initialize(AyContext ct = null)
|
|
{
|
|
//set to current servers boot version so as to not trigger messaging at client on login until job has had a chance to set
|
|
LATEST_VERSION = Util.AyaNovaVersion.VersionString;
|
|
CHANGE_LOG_URL = "https://ayanova.com/docs/changelog/";//just something to default to, should never come up as it's not a different version at this point
|
|
|
|
//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 |