From aa51b67ea1f767acced1958022d4891e4ede8648 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 16 Dec 2023 10:07:18 -0500 Subject: [PATCH] Handle startup jobs a bit better --- .../Extensions/JobCodeExtensions.cs | 25 +++++++++++++++++++ src/Tgstation.Server.Host/Jobs/JobService.cs | 8 +++++- .../Live/Instance/JobsHubTests.cs | 7 +++--- .../Live/TestLiveServer.cs | 18 ++++++------- 4 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 src/Tgstation.Server.Api/Extensions/JobCodeExtensions.cs diff --git a/src/Tgstation.Server.Api/Extensions/JobCodeExtensions.cs b/src/Tgstation.Server.Api/Extensions/JobCodeExtensions.cs new file mode 100644 index 0000000000..90c379f824 --- /dev/null +++ b/src/Tgstation.Server.Api/Extensions/JobCodeExtensions.cs @@ -0,0 +1,25 @@ +using System; + +using Tgstation.Server.Api.Models; + +namespace Tgstation.Server.Api.Extensions +{ + /// + /// Extension methods for the . + /// + public static class JobCodeExtensions + { + /// + /// If a given can be triggered by TGS startup. + /// + /// The . + /// if the can trigger before startup, otherwise. + public static bool IsServerStartupJob(this JobCode jobCode) + => jobCode switch + { + JobCode.Unknown or JobCode.Move or JobCode.RepositoryClone or JobCode.RepositoryUpdate or JobCode.RepositoryAutoUpdate or JobCode.RepositoryDelete or JobCode.EngineOfficialInstall or JobCode.EngineCustomInstall or JobCode.EngineDelete or JobCode.Deployment or JobCode.AutomaticDeployment or JobCode.WatchdogLaunch or JobCode.WatchdogRestart or JobCode.WatchdogDump => false, + JobCode.StartupWatchdogLaunch or JobCode.StartupWatchdogReattach or JobCode.ReconnectChatBot => true, + _ => throw new InvalidOperationException($"Invalid JobCode: {jobCode}"), + }; + } +} diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs index 87387c60a9..abdb26170c 100644 --- a/src/Tgstation.Server.Host/Jobs/JobService.cs +++ b/src/Tgstation.Server.Host/Jobs/JobService.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging; using Serilog.Context; +using Tgstation.Server.Api.Extensions; using Tgstation.Server.Api.Hubs; using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Common.Extensions; @@ -452,7 +453,12 @@ namespace Tgstation.Server.Host.Jobs } } - var instanceCoreProvider = await activationTcs.Task.WaitAsync(cancellationToken); + var activationTask = activationTcs.Task; + + Debug.Assert(activationTask.IsCompleted || job.JobCode.Value.IsServerStartupJob(), "Non-server startup job registered before activation!"); + + var instanceCoreProvider = await activationTask.WaitAsync(cancellationToken); + QueueHubUpdate(job.ToApi(), false); logger.LogTrace("Starting job..."); diff --git a/tests/Tgstation.Server.Tests/Live/Instance/JobsHubTests.cs b/tests/Tgstation.Server.Tests/Live/Instance/JobsHubTests.cs index 8f42d165d4..19be3fe30b 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/JobsHubTests.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/JobsHubTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Tgstation.Server.Api.Extensions; using Tgstation.Server.Api.Hubs; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Request; @@ -209,9 +210,7 @@ namespace Tgstation.Server.Tests.Live.Instance } else { - var wasMissableJob = job.JobCode == JobCode.ReconnectChatBot - || job.JobCode == JobCode.StartupWatchdogLaunch - || job.JobCode == JobCode.StartupWatchdogReattach; + var wasMissableJob = job.JobCode.Value.IsServerStartupJob(); Assert.IsTrue(wasMissableJob, $"Found unexpected missed job: #{job.Id.Value} - {job.JobCode} - {job.Description}"); ++missableMissedJobs; } diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index 52b0b3f90e..5707027a92 100644 --- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -28,6 +28,7 @@ using Newtonsoft.Json; using Npgsql; using Tgstation.Server.Api; +using Tgstation.Server.Api.Extensions; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Request; using Tgstation.Server.Api.Models.Response; @@ -1653,16 +1654,11 @@ namespace Tgstation.Server.Tests.Live { var jobs = await instanceClient.Jobs.ListActive(null, cancellationToken); if (jobs.Count == 0) - { - var entities = await instanceClient.Jobs.List(null, cancellationToken); - var getTasks = entities - .Select(e => instanceClient.Jobs.GetId(e, cancellationToken)) - .ToList(); - - jobs = (await ValueTaskExtensions.WhenAll(getTasks)) + jobs = (await instanceClient.Jobs.List(null, cancellationToken)) .Where(x => x.StartedAt.Value > preStartupTime) - .ToList(); - } + .ToList(); + else + jobs = jobs.Where(x => x.JobCode.Value.IsServerStartupJob()).ToList(); await using var jrt = new JobsRequiredTest(instanceClient.Jobs); foreach (var job in jobs) @@ -1679,9 +1675,9 @@ namespace Tgstation.Server.Tests.Live var edgeVersion = await EngineTest.GetEdgeVersion(EngineType.Byond, fileDownloader, cancellationToken); await using (var adminClient = await CreateAdminClient(server.ApiUrl, cancellationToken)) { + await jobsHubTest.WaitForReconnect(cancellationToken); var instanceClient = adminClient.Instances.CreateClient(instance); await WaitForInitialJobs(instanceClient); - await jobsHubTest.WaitForReconnect(cancellationToken); var dd = await instanceClient.DreamDaemon.Read(cancellationToken); @@ -1722,9 +1718,9 @@ namespace Tgstation.Server.Tests.Live serverTask = server.Run(cancellationToken).AsTask(); await using (var adminClient = await CreateAdminClient(server.ApiUrl, cancellationToken)) { + await jobsHubTest.WaitForReconnect(cancellationToken); var instanceClient = adminClient.Instances.CreateClient(instance); await WaitForInitialJobs(instanceClient); - await jobsHubTest.WaitForReconnect(cancellationToken); var currentDD = await instanceClient.DreamDaemon.Read(cancellationToken); Assert.AreEqual(expectedCompileJobId, currentDD.ActiveCompileJob.Id.Value);