From 2a3a72a1e74bc63b23355cb0b35ca20de04939b8 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sun, 25 Jun 2023 22:57:42 -0400 Subject: [PATCH] Convert to `BackgroundService` where applicable Also fix case of localhost SqlServer in SetupWizard --- .../Setup/SetupWizard.cs | 9 ++-- .../System/SystemDManager.cs | 51 +++---------------- .../System/WindowsNetworkPromptReaper.cs | 43 ++-------------- .../Setup/TestSetupWizard.cs | 21 +++++--- 4 files changed, 28 insertions(+), 96 deletions(-) diff --git a/src/Tgstation.Server.Host/Setup/SetupWizard.cs b/src/Tgstation.Server.Host/Setup/SetupWizard.cs index 775cbe98e0..f5e4deb0f8 100644 --- a/src/Tgstation.Server.Host/Setup/SetupWizard.cs +++ b/src/Tgstation.Server.Host/Setup/SetupWizard.cs @@ -32,7 +32,7 @@ using YamlDotNet.Serialization; namespace Tgstation.Server.Host.Setup { /// - sealed class SetupWizard : IHostedService + sealed class SetupWizard : BackgroundService { /// /// The for the . @@ -129,15 +129,12 @@ namespace Tgstation.Server.Host.Setup } /// - public async Task StartAsync(CancellationToken cancellationToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken) { await CheckRunWizard(cancellationToken); applicationLifetime.StopApplication(); } - /// - public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; - /// /// A prompt for a yes or no value. /// @@ -493,7 +490,7 @@ namespace Tgstation.Server.Host.Setup bool useWinAuth; if (databaseConfiguration.DatabaseType == DatabaseType.SqlServer && platformIdentifier.IsWindows) { - var defaultResponse = serverAddressEntry.AddressList.Any(IPAddress.IsLoopback) + var defaultResponse = serverAddressEntry?.AddressList.Any(IPAddress.IsLoopback) ?? false ? (bool?)true : null; useWinAuth = await PromptYesNo("Use Windows Authentication?", defaultResponse, cancellationToken); diff --git a/src/Tgstation.Server.Host/System/SystemDManager.cs b/src/Tgstation.Server.Host/System/SystemDManager.cs index 99f4ade686..9ce09a1387 100644 --- a/src/Tgstation.Server.Host/System/SystemDManager.cs +++ b/src/Tgstation.Server.Host/System/SystemDManager.cs @@ -17,7 +17,7 @@ namespace Tgstation.Server.Host.System /// /// Implements the SystemD notify service protocol. /// - sealed class SystemDManager : IHostedService, IRestartHandler, IDisposable + sealed class SystemDManager : BackgroundService, IRestartHandler, IDisposable { /// /// The sd_notify command for notifying the watchdog we are alive. @@ -44,16 +44,6 @@ namespace Tgstation.Server.Host.System /// readonly ILogger logger; - /// - /// The for . - /// - readonly CancellationTokenSource watchdogCts; - - /// - /// The main task executing in the . - /// - Task runTask; - /// /// If TGS is going to restart. /// @@ -87,22 +77,13 @@ namespace Tgstation.Server.Host.System this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); restartRegistration = serverControl.RegisterForRestart(this); - try - { - watchdogCts = new CancellationTokenSource(); - } - catch - { - restartRegistration.Dispose(); - throw; - } } /// - public void Dispose() + public override void Dispose() { + base.Dispose(); restartRegistration.Dispose(); - watchdogCts.Dispose(); } /// @@ -114,36 +95,16 @@ namespace Tgstation.Server.Host.System } /// - public Task StartAsync(CancellationToken cancellationToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken) { if (SendSDNotify(SDNotifyWatchdog)) - { - logger.LogDebug("SystemD detected"); - runTask = RunAsync(watchdogCts.Token); - } - else { logger.LogDebug("SystemD not detected"); - runTask = Task.CompletedTask; + return; } - return Task.CompletedTask; - } + logger.LogDebug("SystemD detected"); - /// - public async Task StopAsync(CancellationToken cancellationToken) - { - watchdogCts.Cancel(); - await runTask.WithToken(cancellationToken); - } - - /// - /// Runs the . - /// - /// The for the operation. - /// A representing the running operation. - async Task RunAsync(CancellationToken cancellationToken) - { if (applicationLifetime.ApplicationStarted.IsCancellationRequested) throw new InvalidOperationException("RunAsync called after application started!"); diff --git a/src/Tgstation.Server.Host/System/WindowsNetworkPromptReaper.cs b/src/Tgstation.Server.Host/System/WindowsNetworkPromptReaper.cs index ce0fa3a88b..6578457672 100644 --- a/src/Tgstation.Server.Host/System/WindowsNetworkPromptReaper.cs +++ b/src/Tgstation.Server.Host/System/WindowsNetworkPromptReaper.cs @@ -16,7 +16,7 @@ using Tgstation.Server.Host.Utils; namespace Tgstation.Server.Host.System { /// - sealed class WindowsNetworkPromptReaper : IHostedService, INetworkPromptReaper, IDisposable + sealed class WindowsNetworkPromptReaper : BackgroundService, INetworkPromptReaper { /// /// Number of times to send the button click message. Should be at least 2 or it may fail to focus the window. @@ -38,21 +38,11 @@ namespace Tgstation.Server.Host.System /// readonly ILogger logger; - /// - /// The for the . - /// - readonly CancellationTokenSource cancellationTokenSource; - /// /// The list of s registered. /// readonly List registeredProcesses; - /// - /// The representing the lifetime of the . - /// - Task runTask; - /// /// Callback for . /// @@ -106,26 +96,6 @@ namespace Tgstation.Server.Host.System this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); registeredProcesses = new List(); - cancellationTokenSource = new CancellationTokenSource(); - } - - /// - public void Dispose() => cancellationTokenSource.Dispose(); - - /// - public Task StartAsync(CancellationToken cancellationToken) - { - runTask = Run(cancellationTokenSource.Token); - return Task.CompletedTask; - } - - /// - public async Task StopAsync(CancellationToken cancellationToken) - { - logger.LogTrace("Stopping network prompt reaper..."); - cancellationTokenSource.Cancel(); - await runTask; - registeredProcesses.Clear(); } /// @@ -150,12 +120,8 @@ namespace Tgstation.Server.Host.System }, TaskScheduler.Current); } - /// - /// Main loop for the . - /// - /// The for the operation. - /// A representing the running operation. - async Task Run(CancellationToken cancellationToken) + /// + protected override async Task ExecuteAsync(CancellationToken cancellationToken) { logger.LogDebug("Starting network prompt reaper..."); try @@ -221,7 +187,8 @@ namespace Tgstation.Server.Host.System } finally { - logger.LogDebug("Exiting network prompt reaper..."); + registeredProcesses.Clear(); + logger.LogTrace("Exiting network prompt reaper..."); } } } diff --git a/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs b/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs index 8edbf59c70..4ee9dfd632 100644 --- a/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs +++ b/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs @@ -91,13 +91,13 @@ namespace Tgstation.Server.Host.Setup.Tests mockPlatformIdentifier.SetupGet(x => x.IsWindows).Returns(true).Verifiable(); mockAsyncDelayer.Setup(x => x.Delay(It.IsAny(), It.IsAny())).Returns(Task.CompletedTask).Verifiable(); - await wizard.StartAsync(default); + await RunWizard(); testGeneralConfig.SetupWizardMode = SetupWizardMode.Force; - await Assert.ThrowsExceptionAsync(() => wizard.StartAsync(default)); + await Assert.ThrowsExceptionAsync(() => RunWizard()); testGeneralConfig.SetupWizardMode = SetupWizardMode.Only; - await Assert.ThrowsExceptionAsync(() => wizard.StartAsync(default)); + await Assert.ThrowsExceptionAsync(() => RunWizard()); mockConsole.SetupGet(x => x.Available).Returns(true).Verifiable(); mockIOManager.Setup(x => x.FileExists(It.IsNotNull(), It.IsAny())).Returns(Task.FromResult(true)).Verifiable(); @@ -279,13 +279,20 @@ namespace Tgstation.Server.Host.Setup.Tests .Returns(Task.CompletedTask) .Verifiable(); - await wizard.StartAsync(default); + async Task RunWizard() + { + await wizard.StartAsync(default); + await wizard.ExecuteTask; + await wizard.StopAsync(default); + } + + await RunWizard(); //first real run - await wizard.StartAsync(default); + await RunWizard(); //second run mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull(), It.IsAny())).Returns(Task.FromResult(Encoding.UTF8.GetBytes(String.Empty))).Verifiable(); - await wizard.StartAsync(default); + await RunWizard(); //third run testGeneralConfig.SetupWizardMode = SetupWizardMode.Autodetect; @@ -309,7 +316,7 @@ namespace Tgstation.Server.Host.Setup.Tests return Task.CompletedTask; }).Verifiable(); - await Assert.ThrowsExceptionAsync(() => wizard.StartAsync(default)); + await Assert.ThrowsExceptionAsync(() => RunWizard()); Assert.AreEqual(finalInputSequence.Count, inputPos); mockFailCommand.VerifyAll();