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();