diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index fe4ac6561c..0f3d160564 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -382,6 +382,17 @@ namespace Tgstation.Server.Host.Components // build current commit data if it's missing await UpdateRevInfo(repo.Head, false, null); + var preserveTestMerges = repositorySettings.AutoUpdatesKeepTestMerges.Value; + var remoteDeploymentManager = remoteDeploymentManagerFactory.CreateRemoteDeploymentManager( + metadata, + repo.RemoteGitProvider.Value); + + var updatedTestMerges = await remoteDeploymentManager.RemoveMergedTestMerges( + repo, + repositorySettings, + currentRevInfo, + cancellationToken); + var result = await repo.MergeOrigin( NextProgressReporter("Merge Origin"), repositorySettings.CommitterName, @@ -389,21 +400,10 @@ namespace Tgstation.Server.Host.Components true, cancellationToken); - var preserveTestMerges = repositorySettings.AutoUpdatesKeepTestMerges.Value; - var remoteDeploymentManager = remoteDeploymentManagerFactory.CreateRemoteDeploymentManager( - metadata, - repo.RemoteGitProvider.Value); - // take appropriate auto update actions var shouldSyncTracked = false; if (result.HasValue) { - var updatedTestMerges = await remoteDeploymentManager.RemoveMergedTestMerges( - repo, - repositorySettings, - currentRevInfo, - cancellationToken); - if (updatedTestMerges.Count == 0) { logger.LogTrace("All test merges have been merged on remote"); @@ -517,7 +517,12 @@ namespace Tgstation.Server.Host.Components RepositoryAutoUpdateJob, cancellationToken); - await jobManager.WaitForJobCompletion(repositoryUpdateJob, null, cancellationToken, cancellationToken); + var repoUpdateJobResult = await jobManager.WaitForJobCompletion(repositoryUpdateJob, null, cancellationToken, cancellationToken); + if (repoUpdateJobResult == false) + { + logger.LogWarning("Aborting auto-update due to repository update error!"); + continue; + } Job compileProcessJob; using (var repo = await RepositoryManager.LoadRepository(cancellationToken)) diff --git a/src/Tgstation.Server.Host/Jobs/IJobManager.cs b/src/Tgstation.Server.Host/Jobs/IJobManager.cs index f02f765994..c0ae74cd19 100644 --- a/src/Tgstation.Server.Host/Jobs/IJobManager.cs +++ b/src/Tgstation.Server.Host/Jobs/IJobManager.cs @@ -33,8 +33,8 @@ namespace Tgstation.Server.Host.Jobs /// The to cancel the . If the TGS user will be used. /// A that will cancel the . /// The for the operation. - /// A representing the . - Task WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken); + /// A representing the . Results in if the completed without errors, if errors occurred, or if the job isn't registered. + Task WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken); /// /// Cancels a give . diff --git a/src/Tgstation.Server.Host/Jobs/JobHandler.cs b/src/Tgstation.Server.Host/Jobs/JobHandler.cs index 57aae60fdb..9d9c692c07 100644 --- a/src/Tgstation.Server.Host/Jobs/JobHandler.cs +++ b/src/Tgstation.Server.Host/Jobs/JobHandler.cs @@ -30,20 +30,20 @@ namespace Tgstation.Server.Host.Jobs readonly CancellationTokenSource cancellationTokenSource; /// - /// A taking a and returning a that the will wrap. + /// A taking a and returning a that the will wrap. /// - readonly Func jobActivator; + readonly Func> jobActivator; /// /// The being run. /// - Task task; + Task task; /// /// Initializes a new instance of the class. /// /// The value of . - public JobHandler(Func jobActivator) + public JobHandler(Func> jobActivator) { this.jobActivator = jobActivator ?? throw new ArgumentNullException(nameof(jobActivator)); cancellationTokenSource = new CancellationTokenSource(); @@ -56,8 +56,8 @@ namespace Tgstation.Server.Host.Jobs /// Wait for to complete. /// /// The for the operation. - /// A representing the running operation. - public Task Wait(CancellationToken cancellationToken) + /// A representing the job. Results in if the job completed without errors, otherwise. + public Task Wait(CancellationToken cancellationToken) { if (task == null) throw new InvalidOperationException("Job not started!"); diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs index b4baca7533..0cc8c05ec0 100644 --- a/src/Tgstation.Server.Host/Jobs/JobService.cs +++ b/src/Tgstation.Server.Host/Jobs/JobService.cs @@ -247,7 +247,7 @@ namespace Tgstation.Server.Host.Jobs } /// - public async Task WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken) + public async Task WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(job); @@ -259,7 +259,7 @@ namespace Tgstation.Server.Host.Jobs lock (synchronizationLock) { if (!jobs.TryGetValue(job.Id.Value, out handler)) - return; + return null; noMoreJobsShouldStart = this.noMoreJobsShouldStart; } @@ -268,11 +268,14 @@ namespace Tgstation.Server.Host.Jobs await Extensions.TaskExtensions.InfiniteTask.WaitAsync(cancellationToken); Task cancelTask = null; + bool result; using (jobCancellationToken.Register(() => cancelTask = CancelJob(job, canceller, true, cancellationToken))) - await handler.Wait(cancellationToken); + result = await handler.Wait(cancellationToken); if (cancelTask != null) await cancelTask; + + return result; } /// @@ -291,12 +294,14 @@ namespace Tgstation.Server.Host.Jobs /// The for the . /// The for the operation. /// A representing the running operation. - async Task RunJob(Job job, JobEntrypoint operation, CancellationToken cancellationToken) + async Task RunJob(Job job, JobEntrypoint operation, CancellationToken cancellationToken) { using (LogContext.PushProperty(SerilogContextHelper.JobIdContextProperty, job.Id)) try { void LogException(Exception ex) => logger.LogDebug(ex, "Job {jobId} exited with error!", job.Id); + + var result = false; try { var oldJob = job; @@ -334,6 +339,7 @@ namespace Tgstation.Server.Host.Jobs cancellationToken); logger.LogDebug("Job {jobId} completed!", job.Id); + result = true; } catch (OperationCanceledException ex) { @@ -368,6 +374,8 @@ namespace Tgstation.Server.Host.Jobs // DCT: Cancellation token is for job, operation should always run await databaseContext.Save(CancellationToken.None); }); + + return result; } finally { diff --git a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs index 7389acbc81..e5d01244a2 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs @@ -39,7 +39,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests .Returns(Task.CompletedTask); mockSetup .Setup(x => x.WaitForJobCompletion(It.IsNotNull(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(Task.CompletedTask); + .Returns(Task.FromResult(true)); mockJobManager = mockSetup.Object; } diff --git a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs index b11b0ea074..76bafe981f 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs @@ -76,7 +76,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests .Returns(Task.CompletedTask); mockSetup .Setup(x => x.WaitForJobCompletion(It.IsNotNull(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(Task.CompletedTask); + .Returns(Task.FromResult(true)); var mockJobManager = mockSetup.Object; await using var provider = new IrcProvider(mockJobManager, new AsyncDelayer(), loggerFactory.CreateLogger(), Mock.Of(), new ChatBot { diff --git a/tests/Tgstation.Server.Host.Tests/Jobs/TestJobHandler.cs b/tests/Tgstation.Server.Host.Tests/Jobs/TestJobHandler.cs index ed8660ec0e..b8a61b4b29 100644 --- a/tests/Tgstation.Server.Host.Tests/Jobs/TestJobHandler.cs +++ b/tests/Tgstation.Server.Host.Tests/Jobs/TestJobHandler.cs @@ -11,10 +11,11 @@ namespace Tgstation.Server.Host.Jobs.Tests Task currentWaitTask; bool cancelled; - async Task TestJob(CancellationToken cancellationToken) + async Task TestJob(CancellationToken cancellationToken) { await currentWaitTask; cancelled = cancellationToken.IsCancellationRequested; + return true; } [TestMethod]