diff --git a/src/Tgstation.Server.Host/Components/DmbFactory.cs b/src/Tgstation.Server.Host/Components/DmbFactory.cs index 40d50d393a..5609c3f08b 100644 --- a/src/Tgstation.Server.Host/Components/DmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/DmbFactory.cs @@ -36,6 +36,11 @@ namespace Tgstation.Server.Host.Components /// The for /// readonly CancellationTokenSource cleanupCts; + + /// + /// The the belongs to + /// + readonly long instanceId; /// /// representing calls to @@ -57,10 +62,12 @@ namespace Tgstation.Server.Host.Components /// /// The value of /// The value of - public DmbFactory(IDatabaseContextFactory databaseContextFactory, IIOManager ioManager) + /// The used to populate + public DmbFactory(IDatabaseContextFactory databaseContextFactory, IIOManager ioManager, Models.Instance instance) { this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); + instanceId = instance?.Id ?? throw new ArgumentNullException(nameof(instance)); cleanupCts = new CancellationTokenSource(); jobLockCounts = new Dictionary(); @@ -92,12 +99,25 @@ namespace Tgstation.Server.Host.Components } /// - public void LoadCompileJob(CompileJob job) + public Task LoadCompileJob(CompileJob job, CancellationToken cancellationToken) => LoadCompileJob(job, true, cancellationToken); + + async Task LoadCompileJob(CompileJob job, bool setAsStagedInDb, CancellationToken cancellationToken) { if (job == null) throw new ArgumentNullException(nameof(job)); if (!job.DMApiValidated || job.Job.Cancelled || job.Job.ExceptionDetails != null || job.Job.StoppedAt == null) throw new InvalidOperationException("Cannot load incomplete compile job!"); + if (setAsStagedInDb) + await databaseContextFactory.UseContext(async db => + { + var ddsettings = new DreamDaemonSettings + { + InstanceId = instanceId + }; + db.DreamDaemonSettings.Attach(ddsettings); + ddsettings.StagedCompileJob = job; + await db.Save(cancellationToken).ConfigureAwait(false); + }).ConfigureAwait(false); lock (this) { var oldDmbProvider = nextDmbProvider; @@ -130,13 +150,16 @@ namespace Tgstation.Server.Host.Components /// public Task StartAsync(CancellationToken cancellationToken) => databaseContextFactory.UseContext(async (db) => { - var cj = await db.CompileJobs.OrderByDescending(x => x.Job.StoppedAt).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); + //where complete clause not necessary, only successful COMPILEjobs get in the db + var cj = await db.Instances.Where(x => x.Id == instanceId).SelectMany(x => x.CompileJobs).OrderByDescending(x => x.Job.StoppedAt).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); if (cj == default(CompileJob)) return; - LoadCompileJob(cj); + var directoriesTask = ioManager.GetDirectories(".", cancellationToken); + var compileJobTask = LoadCompileJob(cj, false, cancellationToken); //delete all other compile jobs - var directories = await ioManager.GetDirectories(".", cancellationToken).ConfigureAwait(false); + var directories = await directoriesTask.ConfigureAwait(false); await Task.WhenAll(directories.Where(x => x != cj.Job.ToString()).Select(x => ioManager.DeleteDirectory(x, cancellationToken))).ConfigureAwait(false); + await compileJobTask.ConfigureAwait(false); }); /// diff --git a/src/Tgstation.Server.Host/Components/DreamMaker.cs b/src/Tgstation.Server.Host/Components/DreamMaker.cs index e51b301ef0..75ac5c271b 100644 --- a/src/Tgstation.Server.Host/Components/DreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/DreamMaker.cs @@ -172,7 +172,7 @@ namespace Tgstation.Server.Host.Components /// The for the operation /// The for the operation /// A representing the running operation - async Task ModifyDme(Host.Models.CompileJob job, CancellationToken cancellationToken) + async Task ModifyDme(Models.CompileJob job, CancellationToken cancellationToken) { var dirA = ioManager.ConcatPath(job.DirectoryName.ToString(), ADirectoryName); var dmePath = ioManager.ConcatPath(dirA, String.Concat(job.DmeName, DmeExtension)); @@ -288,7 +288,7 @@ namespace Tgstation.Server.Host.Components await configuration.SymlinkStaticFilesTo(ioManager.ResolvePath(dirB), cancellationToken).ConfigureAwait(false); await symATask.ConfigureAwait(false); } - compileJobConsumer.LoadCompileJob(job); + await compileJobConsumer.LoadCompileJob(job, cancellationToken).ConfigureAwait(false); return job; } catch diff --git a/src/Tgstation.Server.Host/Components/ICompileJobConsumer.cs b/src/Tgstation.Server.Host/Components/ICompileJobConsumer.cs index 2e96eb26a9..248590a01f 100644 --- a/src/Tgstation.Server.Host/Components/ICompileJobConsumer.cs +++ b/src/Tgstation.Server.Host/Components/ICompileJobConsumer.cs @@ -1,11 +1,13 @@ using Microsoft.Extensions.Hosting; using System; +using System.Threading; +using System.Threading.Tasks; using Tgstation.Server.Host.Models; namespace Tgstation.Server.Host.Components { interface ICompileJobConsumer : IHostedService, IDisposable { - void LoadCompileJob(CompileJob job); + Task LoadCompileJob(CompileJob job, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index 62112fac9b..7939caed1b 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -28,7 +28,7 @@ namespace Tgstation.Server.Host.Components } /// - public IInstance CreateInstance(Host.Models.Instance metadata) + public IInstance CreateInstance(Models.Instance metadata) { //Create the ioManager for the instance @@ -41,7 +41,7 @@ namespace Tgstation.Server.Host.Components var configurationIoManager = new ResolvingIOManager(instanceIoManager, "Configuration"); var codeModificationsIoMananger = new ResolvingIOManager(instanceIoManager, "CodeModifications"); - var dmbFactory = new DmbFactory(databaseContextFactory, gameIoManager); + var dmbFactory = new DmbFactory(databaseContextFactory, gameIoManager, metadata); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs index 85e6594d9f..99e19e7ef0 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs @@ -26,16 +26,6 @@ namespace Tgstation.Server.Host.Components.Watchdog /// LaunchResult LastLaunchResult { get; } - /// - /// The that is currently live - /// - Models.CompileJob LiveCompileJob { get; } - - /// - /// The that is staged to go live - /// - Models.CompileJob StagedCompileJob { get; } - /// /// The the active server is using /// diff --git a/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs index 445ac39386..ef3688fe7a 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs @@ -29,12 +29,6 @@ namespace Tgstation.Server.Host.Components.Watchdog /// public LaunchResult LastLaunchResult { get; private set; } - /// - public Models.CompileJob LiveCompileJob { get; private set; } - - /// - public Models.CompileJob StagedCompileJob { get; private set; } - /// public DreamDaemonLaunchParameters ActiveLaunchParameters { get; private set; } @@ -69,11 +63,21 @@ namespace Tgstation.Server.Host.Components.Watchdog /// readonly IReattachInfoHandler reattachInfoHandler; + /// + /// The for the + /// + readonly IDatabaseContextFactory databaseContextFactory; + /// /// The for the /// readonly SemaphoreSlim semaphore; + /// + /// The the belongs to + /// + readonly long instanceId; + CancellationTokenSource monitorCts; Task monitorTask; @@ -94,14 +98,18 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the /// The value of /// The value of + /// The value of /// The initial value of - public Watchdog(IChat chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, IServerUpdater serverUpdater, ILogger logger, IReattachInfoHandler reattachInfoHandler, DreamDaemonLaunchParameters initialLaunchParameters) + /// The containing the value of + public Watchdog(IChat chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, IServerUpdater serverUpdater, ILogger logger, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, DreamDaemonLaunchParameters initialLaunchParameters, Models.Instance instance) { this.chat = chat ?? throw new ArgumentNullException(nameof(chat)); this.sessionControllerFactory = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory)); this.dmbFactory = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.reattachInfoHandler = reattachInfoHandler ?? throw new ArgumentNullException(nameof(reattachInfoHandler)); + this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); + instanceId = instance?.Id ?? throw new ArgumentNullException(nameof(instance)); if (serverUpdater == null) throw new ArgumentNullException(nameof(serverUpdater)); @@ -416,11 +424,24 @@ namespace Tgstation.Server.Host.Components.Watchdog using (cancellationToken.Register(() => cancelTcs.SetCanceled())) await Task.WhenAny(allTask, cancelTcs.Task).ConfigureAwait(false); + //update the live and staged jobs in the db + await databaseContextFactory.UseContext(async db => + { + var settings = new Models.DreamDaemonSettings + { + InstanceId = instanceId + }; + var cj = (AlphaIsActive ? alphaServer : bravoServer).Dmb.CompileJob; + db.CompileJobs.Attach(cj); + db.DreamDaemonSettings.Attach(settings); + settings.StagedCompileJob = null; + settings.ActiveCompileJob = cj; + await db.Save(cancellationToken).ConfigureAwait(false); + }).ConfigureAwait(false); + //both servers are now running, alpha is the active server, huzzah AlphaIsActive = doReattach ? reattachInfo.AlphaIsActive : true; - LiveCompileJob = AlphaIsActive ? alphaServer.Dmb.CompileJob : bravoServer.Dmb.CompileJob; LastLaunchResult = alphaLrt.Result; - StagedCompileJob = null; Running = true; if (startMonitor) diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs index 2f666ad6be..5df22cc735 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs @@ -34,6 +34,17 @@ namespace Tgstation.Server.Host.Components.Watchdog /// readonly IReattachInfoHandler reattachInfoHandler; + /// + /// The for the + /// + readonly IDatabaseContextFactory databaseContextFactory; + + /// + /// The for the + /// + readonly Models.Instance instance; + + /// /// Construct a /// @@ -42,16 +53,20 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The value of /// The value of /// The value of - public WatchdogFactory(IChat chat, ISessionControllerFactory sessionManagerFactory, IServerUpdater serverUpdater, ILoggerFactory loggerFactory, IReattachInfoHandler reattachInfoHandler) + /// The value of + /// The value of + public WatchdogFactory(IChat chat, ISessionControllerFactory sessionManagerFactory, IServerUpdater serverUpdater, ILoggerFactory loggerFactory, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, Models.Instance instance) { this.chat = chat ?? throw new ArgumentNullException(nameof(chat)); this.sessionManagerFactory = sessionManagerFactory ?? throw new ArgumentNullException(nameof(sessionManagerFactory)); this.serverUpdater = serverUpdater ?? throw new ArgumentNullException(nameof(serverUpdater)); this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); this.reattachInfoHandler = reattachInfoHandler ?? throw new ArgumentNullException(nameof(reattachInfoHandler)); + this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); + this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); } /// - public IWatchdog CreateWatchdog(IDmbFactory dmbFactory, DreamDaemonLaunchParameters launchParameters) => new Watchdog(chat, sessionManagerFactory, dmbFactory, serverUpdater, loggerFactory.CreateLogger(), reattachInfoHandler, launchParameters); + public IWatchdog CreateWatchdog(IDmbFactory dmbFactory, DreamDaemonLaunchParameters launchParameters) => new Watchdog(chat, sessionManagerFactory, dmbFactory, serverUpdater, loggerFactory.CreateLogger(), reattachInfoHandler, databaseContextFactory, launchParameters, instance); } } diff --git a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs index e69a18aca7..375e4dace8 100644 --- a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs +++ b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs @@ -83,7 +83,7 @@ namespace Tgstation.Server.Host.Controllers var metadata = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (int)DreamDaemonRights.ReadMetadata) != 0; var revision = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (int)DreamDaemonRights.ReadRevision) != 0; - var settings = metadata ? await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstAsync(cancellationToken).ConfigureAwait(false) : null; + var settings = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstAsync(cancellationToken).ConfigureAwait(false); var result = new DreamDaemon(); if(metadata) { @@ -104,8 +104,8 @@ namespace Tgstation.Server.Host.Controllers }; if (revision) { - result.ActiveCompileJob = dd.LiveCompileJob?.ToApi(); - result.StagedCompileJob = dd.StagedCompileJob?.ToApi(); + result.ActiveCompileJob = settings.ActiveCompileJob?.ToApi(); + result.StagedCompileJob = settings.StagedCompileJob?.ToApi(); } return Json(result); diff --git a/src/Tgstation.Server.Host/Models/DatabaseContext.cs b/src/Tgstation.Server.Host/Models/DatabaseContext.cs index 2229e1c9da..554118c0f4 100644 --- a/src/Tgstation.Server.Host/Models/DatabaseContext.cs +++ b/src/Tgstation.Server.Host/Models/DatabaseContext.cs @@ -57,9 +57,7 @@ namespace Tgstation.Server.Host.Models /// public DbSet ChatChannels { get; set; } - /// - /// The s in the - /// + /// public DbSet Jobs { get; set; } ///