From 4757ca977067797f08a5515495ffc1edb52217de Mon Sep 17 00:00:00 2001 From: Dominion Date: Mon, 12 Jun 2023 14:05:23 -0400 Subject: [PATCH 01/33] SemaphoreSlimContext.Lock -> ValueTask --- src/Tgstation.Server.Host/Utils/SemaphoreSlimContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Host/Utils/SemaphoreSlimContext.cs b/src/Tgstation.Server.Host/Utils/SemaphoreSlimContext.cs index cdbe2500713..a33ad5ffb45 100644 --- a/src/Tgstation.Server.Host/Utils/SemaphoreSlimContext.cs +++ b/src/Tgstation.Server.Host/Utils/SemaphoreSlimContext.cs @@ -15,7 +15,7 @@ public sealed class SemaphoreSlimContext : IDisposable /// The to lock. /// The for the operation. /// A resulting in the for the lock. - public static async Task Lock(SemaphoreSlim semaphore, CancellationToken cancellationToken) + public static async ValueTask Lock(SemaphoreSlim semaphore, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(semaphore); cancellationToken.ThrowIfCancellationRequested(); From 0fec639fec1e6979fa5aa2b07f25c30e39ce11c4 Mon Sep 17 00:00:00 2001 From: Dominion Date: Wed, 14 Jun 2023 02:26:54 -0400 Subject: [PATCH 02/33] ValueTask WhenAll Extensions --- .../Extensions/ValueTaskExtensions.cs | 169 ++++++++++++++++++ .../Tgstation.Server.Common.csproj | 1 + 2 files changed, 170 insertions(+) create mode 100644 src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs diff --git a/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs b/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs new file mode 100644 index 00000000000..884b30379ae --- /dev/null +++ b/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace Tgstation.Server.Common.Extensions +{ + /// + /// Extension methods for the and es. + /// + public static class ValueTaskExtensions + { + /// + /// Fully a given list of . + /// + /// The type. + /// An of s. + /// The number of elements in . + /// A representing the combined . + /// An containing any s thrown by the . + public static async ValueTask WhenAll(IEnumerable> tasks, int totalTasks) + { + if (tasks == null) + throw new ArgumentNullException(nameof(tasks)); + + // We don't allocate the list if no task throws + List? exceptions = null; + int i = 0; + var results = new T[totalTasks]; + foreach (var task in tasks) + { + try + { + results[i] = await task.ConfigureAwait(false); + } + catch (Exception ex) + { + exceptions ??= new (totalTasks - i); + exceptions.Add(ex); + } + + ++i; + } + + Debug.Assert(totalTasks == i, "Invalid count specified!"); + + if (exceptions != null) + throw new AggregateException(exceptions); + + return results; + } + + /// + /// Fully a given list of . + /// + /// The type. + /// An of s. + /// A containing the of results based on . + /// An containing any s thrown by the . + public static async ValueTask WhenAll(IReadOnlyList> tasks) + { + if (tasks == null) + throw new ArgumentNullException(nameof(tasks)); + + var totalTasks = tasks.Count; + if (totalTasks == 0) + return Array.Empty(); + + // We don't allocate the list if no task throws + List? exceptions = null; + var results = new T[totalTasks]; + for (var i = 0; i < totalTasks; i++) + try + { + results[i] = await tasks[i].ConfigureAwait(false); + } + catch (Exception ex) + { + exceptions ??= new (totalTasks - i); + exceptions.Add(ex); + } + + return exceptions == null + ? results + : throw new AggregateException(exceptions); + } + + /// + /// Fully a given list of . + /// + /// The type. + /// An of s. + /// A containing the of results based on . + /// An containing any s thrown by the . + public static ValueTask WhenAll(params ValueTask[] tasks) => WhenAll((IReadOnlyList>)tasks); + + /// + /// Fully a given list of . + /// + /// An of s. + /// The number of elements in . + /// A representing the combined . + /// An containing any s thrown by the . + public static async ValueTask WhenAll(IEnumerable tasks, int totalTasks) + { + if (tasks == null) + throw new ArgumentNullException(nameof(tasks)); + + // We don't allocate the list if no task throws + List? exceptions = null; + int i = 0; + foreach (var task in tasks) + { + try + { + await task.ConfigureAwait(false); + } + catch (Exception ex) + { + exceptions ??= new (totalTasks - i); + exceptions.Add(ex); + } + + ++i; + } + + Debug.Assert(totalTasks == i, "Invalid count specified!"); + + if (exceptions != null) + throw new AggregateException(exceptions); + } + + /// + /// Fully a given list of . + /// + /// An of s. + /// A representing the combined . + /// An containing any s thrown by the . + public static async ValueTask WhenAll(IReadOnlyList tasks) + { + if (tasks == null) + throw new ArgumentNullException(nameof(tasks)); + + // We don't allocate the list if no task throws + List? exceptions = null; + foreach (var task in tasks) + try + { + await task.ConfigureAwait(false); + } + catch (Exception ex) + { + exceptions ??= new (); + exceptions.Add(ex); + } + + if (exceptions != null) + throw new AggregateException(exceptions); + } + + /// + /// Fully a given list of . + /// + /// An of s. + /// A representing the combined . + /// An containing any s thrown by the . + public static ValueTask WhenAll(params ValueTask[] tasks) => WhenAll((IReadOnlyList)tasks); + } +} diff --git a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj index d7f263b375e..802abe894ad 100644 --- a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj +++ b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj @@ -23,6 +23,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + From ec726e2f27d1dee88079314a63641e54976a0edb Mon Sep 17 00:00:00 2001 From: Dominion Date: Mon, 12 Jun 2023 15:01:26 -0400 Subject: [PATCH 03/33] CachedResponseStream.Create -> ValueTask --- src/Tgstation.Server.Common/Http/CachedResponseStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Common/Http/CachedResponseStream.cs b/src/Tgstation.Server.Common/Http/CachedResponseStream.cs index 1109435308b..eb007b54a5b 100644 --- a/src/Tgstation.Server.Common/Http/CachedResponseStream.cs +++ b/src/Tgstation.Server.Common/Http/CachedResponseStream.cs @@ -25,7 +25,7 @@ public sealed class CachedResponseStream : Stream /// /// The to build from. /// A resulting in a new . - public static async Task Create(HttpResponseMessage response) + public static async ValueTask Create(HttpResponseMessage response) { if (response == null) throw new ArgumentNullException(nameof(response)); From 764724664c9e051b778b4872a6f20c6de0846634 Mon Sep 17 00:00:00 2001 From: Dominion Date: Mon, 12 Jun 2023 19:17:38 -0400 Subject: [PATCH 04/33] ValueTask ByondManager and ByondInstaller --- .../Components/Byond/ByondInstallerBase.cs | 16 +++--- .../Components/Byond/ByondManager.cs | 53 +++++++++++-------- .../Components/Byond/IByondInstaller.cs | 16 +++--- .../Components/Byond/IByondManager.cs | 12 ++--- .../Components/Byond/PosixByondInstaller.cs | 27 ++++++---- .../Components/Byond/WindowsByondInstaller.cs | 19 +++---- .../Components/InstanceFactory.cs | 2 +- .../Controllers/ByondController.cs | 2 +- .../Extensions/TaskExtensions.cs | 2 +- .../Byond/TestPosixByondInstaller.cs | 6 +-- 10 files changed, 82 insertions(+), 73 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs b/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs index 2291a9a5f9a..99bd2c834f0 100644 --- a/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs +++ b/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs @@ -61,7 +61,7 @@ protected ByondInstallerBase(IIOManager ioManager, IFileDownloader fileDownloade public abstract string GetDreamDaemonName(Version version, out bool supportsCli); /// - public async Task CleanCache(CancellationToken cancellationToken) + public async ValueTask CleanCache(CancellationToken cancellationToken) { try { @@ -72,24 +72,20 @@ await IOManager.DeleteDirectory( CacheDirectoryName), cancellationToken); } - catch (OperationCanceledException) + catch (Exception ex) when (ex is not OperationCanceledException) { - throw; - } - catch (Exception e) - { - Logger.LogWarning(e, "Error deleting BYOND cache!"); + Logger.LogWarning(ex, "Error deleting BYOND cache!"); } } /// - public abstract Task InstallByond(Version version, string path, CancellationToken cancellationToken); + public abstract ValueTask InstallByond(Version version, string path, CancellationToken cancellationToken); /// - public abstract Task UpgradeInstallation(Version version, string path, CancellationToken cancellationToken); + public abstract ValueTask UpgradeInstallation(Version version, string path, CancellationToken cancellationToken); /// - public async Task DownloadVersion(Version version, CancellationToken cancellationToken) + public async ValueTask DownloadVersion(Version version, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(version); diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs index 085a5ce2aae..93618839fdf 100644 --- a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs +++ b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using Tgstation.Server.Api.Models; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Events; using Tgstation.Server.Host.Extensions; using Tgstation.Server.Host.IO; @@ -134,7 +135,7 @@ public ByondManager(IIOManager ioManager, IByondInstaller byondInstaller, IEvent public void Dispose() => changeDeleteSemaphore.Dispose(); /// - public async Task ChangeVersion( + public async ValueTask ChangeVersion( JobProgressReporter progressReporter, Version version, Stream customVersionStream, @@ -146,12 +147,12 @@ public async Task ChangeVersion( using (await SemaphoreSlimContext.Lock(changeDeleteSemaphore, cancellationToken)) { using var installLock = await AssertAndLockVersion( - progressReporter, - version, - customVersionStream, - false, - allowInstallation, - cancellationToken); + progressReporter, + version, + customVersionStream, + false, + allowInstallation, + cancellationToken); // We reparse the version because it could be changed after a custom install. version = installLock.Version; @@ -176,7 +177,7 @@ await eventConsumer.HandleEvent( } /// - public async Task UseExecutables(Version requiredVersion, string trustDmbFullPath, CancellationToken cancellationToken) + public async ValueTask UseExecutables(Version requiredVersion, string trustDmbFullPath, CancellationToken cancellationToken) { logger.LogTrace( "Acquiring lock on BYOND version {version}...", @@ -204,7 +205,7 @@ public async Task UseExecutables(Version requiredVersion, } /// - public async Task DeleteVersion(JobProgressReporter progressReporter, Version version, CancellationToken cancellationToken) + public async ValueTask DeleteVersion(JobProgressReporter progressReporter, Version version, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(progressReporter); @@ -293,7 +294,7 @@ await ioManager.DeleteFile( /// public async Task StartAsync(CancellationToken cancellationToken) { - async Task GetActiveVersion() + async ValueTask GetActiveVersion() { var activeVersionFileExists = await ioManager.FileExists(ActiveVersionFileName, cancellationToken); return !activeVersionFileExists ? null : await ioManager.ReadAllBytes(ActiveVersionFileName, cancellationToken); @@ -327,7 +328,7 @@ await ioManager.DeleteFile( var installedVersionPaths = new Dictionary(); - async Task ReadVersion(string path) + async ValueTask ReadVersion(string path) { var versionFile = ioManager.ConcatPath(path, VersionFileName); if (!await ioManager.FileExists(versionFile, cancellationToken)) @@ -366,10 +367,16 @@ async Task ReadVersion(string path) installedVersionPaths.Add(ioManager.ResolvePath(version.ToString()), version); } - await Task.WhenAll(directories.Select(ReadVersion)); + await ValueTaskExtensions.WhenAll( + directories + .Select(ReadVersion), + directories.Count); logger.LogTrace("Upgrading BYOND installations..."); - await Task.WhenAll(installedVersionPaths.Select(kvp => byondInstaller.UpgradeInstallation(kvp.Value, kvp.Key, cancellationToken))); + await ValueTaskExtensions.WhenAll( + installedVersionPaths + .Select(kvp => byondInstaller.UpgradeInstallation(kvp.Value, kvp.Key, cancellationToken)), + installedVersionPaths.Count); var activeVersionBytes = await activeVersionBytesTask; if (activeVersionBytes != null) @@ -404,8 +411,8 @@ async Task ReadVersion(string path) /// If this BYOND version is required as part of a locking operation. /// If an installation should be performed if the is not installed. If and an installation is required an will be thrown. /// The for the operation. - /// A resulting in the . - async Task AssertAndLockVersion( + /// A resulting in the . + async ValueTask AssertAndLockVersion( JobProgressReporter progressReporter, Version version, Stream customVersionStream, @@ -509,11 +516,11 @@ async Task AssertAndLockVersion( /// The BYOND being installed with the number set if appropriate. /// Custom zip file to use. Will cause a number to be added. /// The for the operation. - /// A representing the running operation. - async Task InstallVersionFiles(JobProgressReporter progressReporter, Version version, Stream customVersionStream, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask InstallVersionFiles(JobProgressReporter progressReporter, Version version, Stream customVersionStream, CancellationToken cancellationToken) { var installFullPath = ioManager.ResolvePath(version.ToString()); - async Task DirectoryCleanup() + async ValueTask DirectoryCleanup() { await ioManager.DeleteDirectory(installFullPath, cancellationToken); await ioManager.CreateDirectory(installFullPath, cancellationToken); @@ -561,10 +568,10 @@ await ioManager.WriteAllBytes( Encoding.UTF8.GetBytes(version.ToString()), cancellationToken); } - catch (HttpRequestException e) + catch (HttpRequestException ex) { // since the user can easily provide non-exitent version numbers, we'll turn this into a JobException - throw new JobException(ErrorCode.ByondDownloadFail, e); + throw new JobException(ErrorCode.ByondDownloadFail, ex); } catch (OperationCanceledException) { @@ -581,7 +588,7 @@ await ioManager.WriteAllBytes( /// Create and add a new to . /// /// The being added. - /// The representing the installation process. + /// The representing the installation process. /// The new containing the new . ReferenceCountingContainer AddInstallationContainer(Version version, Task installationTask) { @@ -612,8 +619,8 @@ ReferenceCountingContainer AddInstallati /// /// Full path to the .dmb that should be trusted. /// The for the operation. - /// A representing the running operation. - async Task TrustDmbPath(string fullDmbPath, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask TrustDmbPath(string fullDmbPath, CancellationToken cancellationToken) { var trustedFilePath = ioManager.ConcatPath( byondInstaller.PathToUserByondFolder, diff --git a/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs b/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs index cc49610e64f..a263ddf487d 100644 --- a/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs @@ -33,8 +33,8 @@ interface IByondInstaller /// /// The of BYOND to download. /// The for the operation. - /// A resulting in a of the zipfile. - Task DownloadVersion(Version version, CancellationToken cancellationToken); + /// A resulting in a of the zipfile. + ValueTask DownloadVersion(Version version, CancellationToken cancellationToken); /// /// Does actions necessary to get an extracted BYOND installation working. @@ -42,8 +42,8 @@ interface IByondInstaller /// The of BYOND being installed. /// The path to the BYOND installation. /// The for the operation. - /// A representing the running operation. - Task InstallByond(Version version, string path, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask InstallByond(Version version, string path, CancellationToken cancellationToken); /// /// Does actions necessary to get upgrade a BYOND version installed by a previous version of TGS. @@ -51,14 +51,14 @@ interface IByondInstaller /// The of BYOND being installed. /// The path to the BYOND installation. /// The for the operation. - /// A representing the running operation. - Task UpgradeInstallation(Version version, string path, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask UpgradeInstallation(Version version, string path, CancellationToken cancellationToken); /// /// Attempts to cleans the BYOND cache folder for the system. /// /// The for the operation. - /// A representing the running operation. - Task CleanCache(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CleanCache(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Byond/IByondManager.cs b/src/Tgstation.Server.Host/Components/Byond/IByondManager.cs index 58ab6d74808..092034b1c0b 100644 --- a/src/Tgstation.Server.Host/Components/Byond/IByondManager.cs +++ b/src/Tgstation.Server.Host/Components/Byond/IByondManager.cs @@ -32,8 +32,8 @@ public interface IByondManager : IComponentService, IDisposable /// Optional of a custom BYOND version zip file. /// If an installation should be performed if the is not installed. If and an installation is required an will be thrown. /// The for the operation. - /// A representing the running operation. - Task ChangeVersion(JobProgressReporter progressReporter, Version version, Stream customVersionStream, bool allowInstallation, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask ChangeVersion(JobProgressReporter progressReporter, Version version, Stream customVersionStream, bool allowInstallation, CancellationToken cancellationToken); /// /// Deletes a given BYOND version from the disk. @@ -41,8 +41,8 @@ public interface IByondManager : IComponentService, IDisposable /// The for the operation. /// The to delete. /// The for the operation. - /// A representing the running operation. - Task DeleteVersion(JobProgressReporter progressReporter, Version version, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask DeleteVersion(JobProgressReporter progressReporter, Version version, CancellationToken cancellationToken); /// /// Lock the current installation's location and return a . @@ -50,8 +50,8 @@ public interface IByondManager : IComponentService, IDisposable /// The BYOND required. /// The optional full path to .dmb to trust while using the executables. /// The for the operation. - /// A resulting in the requested . - Task UseExecutables( + /// A resulting in the requested . + ValueTask UseExecutables( Version requiredVersion, string trustDmbFullPath, CancellationToken cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs b/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs index cdcb13eb7b9..53a848c8b5a 100644 --- a/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.IO; namespace Tgstation.Server.Host.Components.Byond @@ -77,7 +78,7 @@ public override string GetDreamDaemonName(Version version, out bool supportsCli) } /// - public override Task InstallByond(Version version, string path, CancellationToken cancellationToken) + public override ValueTask InstallByond(Version version, string path, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(version); ArgumentNullException.ThrowIfNull(path); @@ -89,7 +90,7 @@ public override Task InstallByond(Version version, string path, CancellationToke var dreamDaemonScript = String.Format(CultureInfo.InvariantCulture, StandardScript, DreamDaemonExecutableName); var dreamMakerScript = String.Format(CultureInfo.InvariantCulture, StandardScript, DreamMakerExecutableName); - async Task WriteAndMakeExecutable(string pathToScript, string script) + async ValueTask WriteAndMakeExecutable(string pathToScript, string script) { Logger.LogTrace("Writing script {path}:{newLine}{scriptContents}", pathToScript, Environment.NewLine, script); await IOManager.WriteAllBytes(pathToScript, Encoding.ASCII.GetBytes(script), cancellationToken); @@ -98,13 +99,17 @@ async Task WriteAndMakeExecutable(string pathToScript, string script) var basePath = IOManager.ConcatPath(path, ByondManager.BinPath); - var task = Task.WhenAll( - WriteAndMakeExecutable( - IOManager.ConcatPath(basePath, GetDreamDaemonName(version, out var _)), - dreamDaemonScript), - WriteAndMakeExecutable( - IOManager.ConcatPath(basePath, DreamMakerName), - dreamMakerScript)); + var ddTask = WriteAndMakeExecutable( + IOManager.ConcatPath(basePath, GetDreamDaemonName(version, out var _)), + dreamDaemonScript); + + var dmTask = WriteAndMakeExecutable( + IOManager.ConcatPath(basePath, DreamMakerName), + dreamMakerScript); + + var task = ValueTaskExtensions.WhenAll( + ddTask, + dmTask); postWriteHandler.HandleWrite(IOManager.ConcatPath(basePath, DreamDaemonExecutableName)); postWriteHandler.HandleWrite(IOManager.ConcatPath(basePath, DreamMakerExecutableName)); @@ -113,12 +118,12 @@ async Task WriteAndMakeExecutable(string pathToScript, string script) } /// - public override Task UpgradeInstallation(Version version, string path, CancellationToken cancellationToken) + public override ValueTask UpgradeInstallation(Version version, string path, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(version); ArgumentNullException.ThrowIfNull(path); - return Task.CompletedTask; + return ValueTask.CompletedTask; } } } diff --git a/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs b/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs index 3bd1e64db1a..0bcfc70b103 100644 --- a/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Options; using Tgstation.Server.Api.Models; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.Jobs; @@ -113,9 +114,9 @@ public override string GetDreamDaemonName(Version version, out bool supportsCli) } /// - public override Task InstallByond(Version version, string path, CancellationToken cancellationToken) + public override ValueTask InstallByond(Version version, string path, CancellationToken cancellationToken) { - var tasks = new List + var tasks = new List(3) { SetNoPromptTrusted(path, cancellationToken), InstallDirectX(path, cancellationToken), @@ -124,11 +125,11 @@ public override Task InstallByond(Version version, string path, CancellationToke if (!generalConfiguration.SkipAddingByondFirewallException) tasks.Add(AddDreamDaemonToFirewall(version, path, cancellationToken)); - return Task.WhenAll(tasks); + return ValueTaskExtensions.WhenAll(tasks); } /// - public override async Task UpgradeInstallation(Version version, string path, CancellationToken cancellationToken) + public override async ValueTask UpgradeInstallation(Version version, string path, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(version); ArgumentNullException.ThrowIfNull(path); @@ -153,7 +154,7 @@ public override async Task UpgradeInstallation(Version version, string path, Can /// The path to the BYOND installation. /// The for the operation. /// A representing the running operation. - async Task SetNoPromptTrusted(string path, CancellationToken cancellationToken) + async ValueTask SetNoPromptTrusted(string path, CancellationToken cancellationToken) { var configPath = IOManager.ConcatPath(path, ByondConfigDirectory); await IOManager.CreateDirectory(configPath, cancellationToken); @@ -171,8 +172,8 @@ await IOManager.WriteAllBytes( /// /// The path to the BYOND installation. /// The for the operation. - /// A representing the running operation. - async Task InstallDirectX(string path, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask InstallDirectX(string path, CancellationToken cancellationToken) { using var lockContext = await SemaphoreSlimContext.Lock(semaphore, cancellationToken); if (installedDirectX) @@ -216,8 +217,8 @@ async Task InstallDirectX(string path, CancellationToken cancellationToken) /// The BYOND . /// The path to the BYOND installation. /// The for the operation. - /// A representing the running operation. - async Task AddDreamDaemonToFirewall(Version version, string path, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask AddDreamDaemonToFirewall(Version version, string path, CancellationToken cancellationToken) { var dreamDaemonName = GetDreamDaemonName(version, out var supportsCli); diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index df1f4217e41..ed5e3b5ebe8 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -418,7 +418,7 @@ public async Task CreateInstance(IBridgeRegistrar bridgeRegistrar, Mo public Task StartAsync(CancellationToken cancellationToken) { CheckSystemCompatibility(); - return byondInstaller.CleanCache(cancellationToken); + return byondInstaller.CleanCache(cancellationToken).AsTask(); } /// diff --git a/src/Tgstation.Server.Host/Controllers/ByondController.cs b/src/Tgstation.Server.Host/Controllers/ByondController.cs index 92c9878d7b5..873a9181407 100644 --- a/src/Tgstation.Server.Host/Controllers/ByondController.cs +++ b/src/Tgstation.Server.Host/Controllers/ByondController.cs @@ -311,7 +311,7 @@ public async Task Delete([FromBody] ByondVersionDeleteRequest mod await jobManager.RegisterOperation( job, (instanceCore, databaseContextFactory, job, progressReporter, jobCancellationToken) - => instanceCore.ByondManager.DeleteVersion(progressReporter, version, jobCancellationToken), + => instanceCore.ByondManager.DeleteVersion(progressReporter, version, jobCancellationToken).AsTask(), cancellationToken); var apiResponse = job.ToApi(); diff --git a/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs b/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs index 48644e0cd55..aead718e68c 100644 --- a/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs @@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Extensions { /// - /// Extensions for the class. + /// Extensions for the and es. /// static class TaskExtensions { diff --git a/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs b/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs index 0a96ee493b6..63c706799d4 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs @@ -49,7 +49,7 @@ public async Task TestDownload() var mockFileDownloader = new Mock(); var installer = new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, mockFileDownloader.Object, mockLogger.Object); - await Assert.ThrowsExceptionAsync(() => installer.DownloadVersion(null, default)); + await Assert.ThrowsExceptionAsync(async () => await installer.DownloadVersion(null, default)); var ourArray = Array.Empty(); mockFileDownloader @@ -78,8 +78,8 @@ public async Task TestInstallByond() var installer = new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, mockFileDownloader, mockLogger.Object); const string FakePath = "fake"; - await Assert.ThrowsExceptionAsync(() => installer.InstallByond(null, null, default)); - await Assert.ThrowsExceptionAsync(() => installer.InstallByond(new Version(123,252345), null, default)); + await Assert.ThrowsExceptionAsync(async () => await installer.InstallByond(null, null, default)); + await Assert.ThrowsExceptionAsync(async () => await installer.InstallByond(new Version(123,252345), null, default)); await installer.InstallByond(new Version(511, 1385), FakePath, default); From 71753f5a449ab9dbf99bcde8070ddcc7fa53bb4e Mon Sep 17 00:00:00 2001 From: Dominion Date: Wed, 14 Jun 2023 00:59:34 -0400 Subject: [PATCH 05/33] ValueTask a bunch of Database Functions --- .../Components/Instance.cs | 3 ++- .../Components/InstanceManager.cs | 13 +++++++----- .../Repository/RepositoryUpdateService.cs | 4 ++-- .../Components/Session/ISessionPersistor.cs | 8 ++++---- .../Components/Session/SessionPersistor.cs | 8 ++++---- .../Components/Watchdog/BasicWatchdog.cs | 8 +++----- .../Components/Watchdog/WindowsWatchdog.cs | 2 +- .../Database/DatabaseContext.cs | 4 ++-- .../Database/DatabaseContextFactory.cs | 11 +++++++++- .../Database/DatabaseSeeder.cs | 20 +++++++++---------- .../Database/IDatabaseContext.cs | 8 ++++---- .../Database/IDatabaseContextFactory.cs | 11 ++++++++-- .../Database/IDatabaseSeeder.cs | 8 ++++---- src/Tgstation.Server.Host/Jobs/IJobManager.cs | 4 ++-- src/Tgstation.Server.Host/Jobs/JobService.cs | 5 +++-- .../Chat/Providers/TestDiscordProvider.cs | 2 +- .../Chat/Providers/TestIrcProvider.cs | 2 +- .../Database/TestDatabaseContextFactory.cs | 6 +++--- .../Swarm/TestableSwarmNode.cs | 12 +++++++---- tests/Tgstation.Server.Tests/TestDatabase.cs | 2 +- 20 files changed, 82 insertions(+), 59 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index 2f3cc1f1bf8..958a266b8f4 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -474,7 +474,8 @@ await repo.ResetToOrigin( await repo.ResetToSha(startSha, progressReporter, CancellationToken.None); throw; } - }); + }) + .AsTask(); #pragma warning restore CA1502 // Cyclomatic complexity /// diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs index b82bec8f03c..46cd7574d43 100644 --- a/src/Tgstation.Server.Host/Components/InstanceManager.cs +++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs @@ -258,7 +258,7 @@ public async Task MoveInstance(Models.Instance instance, string oldPath, Cancell logger.LogDebug("Reverting instance {instanceId}'s path to {oldPath} in the DB...", instance.Id, oldPath); // DCT: Operation must always run - await databaseContextFactory.UseContext(db => + await databaseContextFactory.UseContext2(db => { var targetInstance = new Models.Instance { @@ -544,8 +544,9 @@ async Task Initialize(CancellationToken cancellationToken) await InitializeSwarm(cancellationToken); List dbInstances = null; - var instanceEnumeration = databaseContextFactory.UseContext( - async databaseContext => dbInstances = await databaseContext + + async ValueTask EnumerateInstances(IDatabaseContext databaseContext) + => dbInstances = await databaseContext .Instances .AsQueryable() .Where(x => x.Online.Value && x.SwarmIdentifer == swarmConfiguration.Identifier) @@ -553,12 +554,14 @@ async Task Initialize(CancellationToken cancellationToken) .Include(x => x.ChatSettings) .ThenInclude(x => x.Channels) .Include(x => x.DreamDaemonSettings) - .ToListAsync(cancellationToken)); + .ToListAsync(cancellationToken); + + var instanceEnumeration = databaseContextFactory.UseContext(EnumerateInstances); var factoryStartup = instanceFactory.StartAsync(cancellationToken); var jobManagerStartup = jobService.StartAsync(cancellationToken); - await Task.WhenAll(instanceEnumeration, factoryStartup, jobManagerStartup); + await Task.WhenAll(instanceEnumeration.AsTask(), factoryStartup, jobManagerStartup); var instanceOnliningTasks = dbInstances.Select( async metadata => diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs index 53de9c45c3c..be19c97785d 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs @@ -192,7 +192,7 @@ JobProgressReporter NextProgressReporter(string stage) Id = instanceId, }; - Task CallLoadRevInfo(Models.TestMerge testMergeToAdd = null, string lastOriginCommitSha = null) => databaseContextFactory + ValueTask CallLoadRevInfo(Models.TestMerge testMergeToAdd = null, string lastOriginCommitSha = null) => databaseContextFactory .UseContext( async databaseContext => { @@ -243,7 +243,7 @@ Task CallLoadRevInfo(Models.TestMerge testMergeToAdd = null, string lastOriginCo await CallLoadRevInfo(); // apply new rev info, tracking applied test merges - Task UpdateRevInfo(Models.TestMerge testMergeToAdd = null) => CallLoadRevInfo(testMergeToAdd, lastRevisionInfo.OriginCommitSha); + ValueTask UpdateRevInfo(Models.TestMerge testMergeToAdd = null) => CallLoadRevInfo(testMergeToAdd, lastRevisionInfo.OriginCommitSha); try { diff --git a/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs b/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs index 3028e6daf43..97b9065b474 100644 --- a/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs +++ b/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs @@ -13,8 +13,8 @@ public interface ISessionPersistor /// /// The to save. /// The for the operation. - /// A representing the running operation. - Task Save(ReattachInformation reattachInformation, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Save(ReattachInformation reattachInformation, CancellationToken cancellationToken); /// /// Load a saved . @@ -27,7 +27,7 @@ public interface ISessionPersistor /// Clear any stored . /// /// The for the operation. - /// A representing the running operation. - Task Clear(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Clear(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs index cd16cfd376a..d452f4fac6f 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs @@ -65,7 +65,7 @@ public SessionPersistor( } /// - public Task Save(ReattachInformation reattachInformation, CancellationToken cancellationToken) => databaseContextFactory.UseContext(async (db) => + public ValueTask Save(ReattachInformation reattachInformation, CancellationToken cancellationToken) => databaseContextFactory.UseContext(async (db) => { ArgumentNullException.ThrowIfNull(reattachInformation); @@ -212,7 +212,7 @@ await db } /// - public Task Clear(CancellationToken cancellationToken) => databaseContextFactory + public ValueTask Clear(CancellationToken cancellationToken) => databaseContextFactory .UseContext( db => { @@ -226,8 +226,8 @@ public Task Clear(CancellationToken cancellationToken) => databaseContextFactory /// The to use. /// If an SQL DELETE WHERE command should be used rather than an Entity Framework transaction. /// The for the operation. - /// A representing the running operation. - async Task ClearImpl(IDatabaseContext databaseContext, bool instant, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask ClearImpl(IDatabaseContext databaseContext, bool instant, CancellationToken cancellationToken) { var baseQuery = databaseContext .ReattachInformations diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs index 713a7e193a6..fce97b6ee64 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs @@ -270,11 +270,9 @@ await ReattachFailure( /// Called to save the current into the when initially launched. /// /// The for the operation. - /// A representing the running operation. - protected virtual Task SessionStartupPersist(CancellationToken cancellationToken) - { - return SessionPersistor.Save(Server.ReattachInformation, cancellationToken); - } + /// A representing the running operation. + protected virtual ValueTask SessionStartupPersist(CancellationToken cancellationToken) + => SessionPersistor.Save(Server.ReattachInformation, cancellationToken); /// /// Handler for when the is . diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs index e797127e3ba..c8c8ce67b54 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs @@ -244,7 +244,7 @@ protected virtual async Task ApplyInitialDmb(CancellationToken cancellationToken } /// - protected override async Task SessionStartupPersist(CancellationToken cancellationToken) + protected override async ValueTask SessionStartupPersist(CancellationToken cancellationToken) { await ApplyInitialDmb(cancellationToken); await base.SessionStartupPersist(cancellationToken); diff --git a/src/Tgstation.Server.Host/Database/DatabaseContext.cs b/src/Tgstation.Server.Host/Database/DatabaseContext.cs index 7309d6e6399..7689f290609 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseContext.cs @@ -283,7 +283,7 @@ protected DatabaseContext(DbContextOptions dbContextOptions) : base(dbContextOpt public Task Drop(CancellationToken cancellationToken) => Database.EnsureDeletedAsync(cancellationToken); /// - public async Task Migrate(ILogger logger, CancellationToken cancellationToken) + public async ValueTask Migrate(ILogger logger, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(logger); var migrations = await Database.GetAppliedMigrationsAsync(cancellationToken); @@ -396,7 +396,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) /// #pragma warning disable CA1502 // Cyclomatic complexity - public async Task SchemaDowngradeForServerVersion( + public async ValueTask SchemaDowngradeForServerVersion( ILogger logger, Version targetVersion, DatabaseType currentDatabaseType, diff --git a/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs b/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs index 0f6a4fcebdf..367b9f030f7 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs @@ -26,7 +26,16 @@ public DatabaseContextFactory(IServiceScopeFactory scopeFactory) } /// - public async Task UseContext(Func operation) + public async ValueTask UseContext(Func operation) + { + ArgumentNullException.ThrowIfNull(operation); + + await using var scope = scopeFactory.CreateAsyncScope(); + await operation(scope.ServiceProvider.GetRequiredService()); + } + + /// + public async ValueTask UseContext2(Func operation) { ArgumentNullException.ThrowIfNull(operation); diff --git a/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs b/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs index 00188bfd7fa..b7512c7ae5e 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs @@ -102,7 +102,7 @@ public DatabaseSeeder( } /// - public async Task Initialize(IDatabaseContext databaseContext, CancellationToken cancellationToken) + public async ValueTask Initialize(IDatabaseContext databaseContext, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(databaseContext); @@ -131,7 +131,7 @@ public async Task Initialize(IDatabaseContext databaseContext, CancellationToken } /// - public Task Downgrade(IDatabaseContext databaseContext, Version downgradeVersion, CancellationToken cancellationToken) + public ValueTask Downgrade(IDatabaseContext databaseContext, Version downgradeVersion, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(databaseContext); ArgumentNullException.ThrowIfNull(downgradeVersion); @@ -172,8 +172,8 @@ User SeedAdminUser(IDatabaseContext databaseContext) /// /// The to seed. /// The for the operation. - /// A representing the running operation. - async Task SeedDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask SeedDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken) { var adminUser = SeedAdminUser(databaseContext); @@ -191,8 +191,8 @@ async Task SeedDatabase(IDatabaseContext databaseContext, CancellationToken canc /// /// The to sanitize. /// The for the operation. - /// A representing the running operation. - async Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken) { var admin = await GetAdminUser(databaseContext, cancellationToken); if (admin != null) @@ -270,8 +270,8 @@ async Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken /// /// The to reset the admin password for. /// The for the operation. - /// A representing the running operation. - async Task ResetAdminPassword(IDatabaseContext databaseContext, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask ResetAdminPassword(IDatabaseContext databaseContext, CancellationToken cancellationToken) { var admin = await GetAdminUser(databaseContext, cancellationToken); if (admin != null) @@ -302,8 +302,8 @@ async Task ResetAdminPassword(IDatabaseContext databaseContext, CancellationToke /// /// The to use. /// The for the operation. - /// A resulting in the admin or . If , must be called on . - async Task GetAdminUser(IDatabaseContext databaseContext, CancellationToken cancellationToken) + /// A resulting in the admin or . If , must be called on . + async ValueTask GetAdminUser(IDatabaseContext databaseContext, CancellationToken cancellationToken) { var admin = await databaseContext .Users diff --git a/src/Tgstation.Server.Host/Database/IDatabaseContext.cs b/src/Tgstation.Server.Host/Database/IDatabaseContext.cs index f4468c63f2e..00b90298c67 100644 --- a/src/Tgstation.Server.Host/Database/IDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/IDatabaseContext.cs @@ -109,8 +109,8 @@ public interface IDatabaseContext /// /// The to use. /// The for the operation. - /// A resulting in if the database should be seeded, otherwise. - Task Migrate(ILogger logger, CancellationToken cancellationToken); + /// A resulting in if the database should be seeded, otherwise. + ValueTask Migrate(ILogger logger, CancellationToken cancellationToken); /// /// Attempt to downgrade the schema to the migration used for a given server . @@ -119,8 +119,8 @@ public interface IDatabaseContext /// The tgstation-server that the schema should downgrade for. /// The in use. /// The for the operation. - /// A representing the running operation. - Task SchemaDowngradeForServerVersion( + /// A representing the running operation. + ValueTask SchemaDowngradeForServerVersion( ILogger logger, Version targetVersion, DatabaseType currentDatabaseType, diff --git a/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs b/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs index 7954066e0b7..228d34f498c 100644 --- a/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs +++ b/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs @@ -12,7 +12,14 @@ public interface IDatabaseContextFactory /// Run an in the scope of an . /// /// The operation to run. - /// A representing the running . - Task UseContext(Func operation); + /// A representing the running . + ValueTask UseContext(Func operation); + + /// + /// Run an in the scope of an . + /// + /// The operation to run. + /// A representing the running . + ValueTask UseContext2(Func operation); } } diff --git a/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs b/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs index 8e218c5e616..e888b0093a8 100644 --- a/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs +++ b/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs @@ -14,8 +14,8 @@ interface IDatabaseSeeder /// /// The to setup. /// The for the operation. - /// A representing the running operation. - Task Initialize(IDatabaseContext databaseContext, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Initialize(IDatabaseContext databaseContext, CancellationToken cancellationToken); /// /// Migrate a given down. @@ -23,7 +23,7 @@ interface IDatabaseSeeder /// The to downgrade. /// The migration to downgrade the to. /// The for the operation. - /// A representing the running operation. - Task Downgrade(IDatabaseContext databaseContext, Version downgradeVersion, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Downgrade(IDatabaseContext databaseContext, Version downgradeVersion, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Jobs/IJobManager.cs b/src/Tgstation.Server.Host/Jobs/IJobManager.cs index f02f765994a..4741406a16d 100644 --- a/src/Tgstation.Server.Host/Jobs/IJobManager.cs +++ b/src/Tgstation.Server.Host/Jobs/IJobManager.cs @@ -23,8 +23,8 @@ public interface IJobManager /// The . Should at least have and . If is , the TGS user will be used. /// The for the . /// The for the operation. - /// A representing a running operation. - Task RegisterOperation(Job job, JobEntrypoint operation, CancellationToken cancellationToken); + /// A representing a running operation. + ValueTask RegisterOperation(Job job, JobEntrypoint operation, CancellationToken cancellationToken); /// /// Wait for a given to complete. diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs index 6f8b3901fe5..445d7e235da 100644 --- a/src/Tgstation.Server.Host/Jobs/JobService.cs +++ b/src/Tgstation.Server.Host/Jobs/JobService.cs @@ -87,7 +87,7 @@ public void Dispose() } /// - public Task RegisterOperation(Job job, JobEntrypoint operation, CancellationToken cancellationToken) + public ValueTask RegisterOperation(Job job, JobEntrypoint operation, CancellationToken cancellationToken) => databaseContextFactory.UseContext( async databaseContext => { @@ -168,7 +168,8 @@ public Task StartAsync(CancellationToken cancellationToken) } noMoreJobsShouldStart = false; - }); + }) + .AsTask(); /// public async Task StopAsync(CancellationToken cancellationToken) 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 7389acbc81d..21fabce4d74 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs @@ -36,7 +36,7 @@ public static void Initialize(TestContext _) mockSetup .Setup(x => x.RegisterOperation(It.IsNotNull(), It.IsNotNull(), It.IsAny())) .Callback((job, entrypoint, cancellationToken) => job.StartedBy ??= new User { }) - .Returns(Task.CompletedTask); + .Returns(ValueTask.CompletedTask); mockSetup .Setup(x => x.WaitForJobCompletion(It.IsNotNull(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); 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 b11b0ea0744..87f61edf6f9 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs @@ -73,7 +73,7 @@ public async Task TestConnectAndDisconnect() mockSetup .Setup(x => x.RegisterOperation(It.IsNotNull(), It.IsNotNull(), It.IsAny())) .Callback((job, entrypoint, cancellationToken) => job.StartedBy ??= new User { }) - .Returns(Task.CompletedTask); + .Returns(ValueTask.CompletedTask); mockSetup .Setup(x => x.WaitForJobCompletion(It.IsNotNull(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); diff --git a/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs b/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs index 06d125fcb91..389f2e40878 100644 --- a/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; @@ -41,12 +41,12 @@ public async Task TestWorks() var factory = new DatabaseContextFactory(mockScopeFactory.Object); - await Assert.ThrowsExceptionAsync(() => factory.UseContext(null)); + await Assert.ThrowsExceptionAsync(async () => await factory.UseContext(null)); await factory.UseContext(context => { Assert.AreSame(mockDbo, context); - return Task.CompletedTask; + return ValueTask.CompletedTask; }); mockScopeFactory.VerifyAll(); diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs index 77585c75a58..87ecc100f75 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs @@ -51,7 +51,7 @@ sealed class TestableSwarmNode : IAsyncDisposable readonly Mock mockHttpClient; readonly Mock mockDBContextFactory; readonly Mock mockDatabaseSeeder; - readonly ISetup mockDatabaseSeederInitialize; + readonly ISetup mockDatabaseSeederInitialize; readonly Action recreateControllerAndService; @@ -95,7 +95,7 @@ public TestableSwarmNode( mockDatabaseSeederInitialize = new Mock().Setup(x => x.Initialize(mockDatabaseContext, It.IsAny())); mockDBContextFactory = new Mock(); mockDBContextFactory - .Setup(x => x.UseContext(It.IsNotNull>())) + .Setup(x => x.UseContext(It.IsNotNull>())) .Callback>((func) => func(mockDatabaseContext)); var mockHttpClientFactory = new Mock(); @@ -226,9 +226,13 @@ private async Task ShutdownService(CancellationToken cancellationToken) Assert.Fail("Initialized twice!"); if (!cancel) - mockDatabaseSeederInitialize.Returns(Task.CompletedTask).Verifiable(); + mockDatabaseSeederInitialize.Returns(ValueTask.CompletedTask).Verifiable(); else - mockDatabaseSeederInitialize.ThrowsAsync(new TaskCanceledException()).Verifiable(); + mockDatabaseSeederInitialize.Returns(async () => + { + await Task.Yield(); + throw new TaskCanceledException(); + }).Verifiable(); Task Invoke() => Service.Initialize(default); diff --git a/tests/Tgstation.Server.Tests/TestDatabase.cs b/tests/Tgstation.Server.Tests/TestDatabase.cs index 12361f0949f..1a5e60d19f1 100644 --- a/tests/Tgstation.Server.Tests/TestDatabase.cs +++ b/tests/Tgstation.Server.Tests/TestDatabase.cs @@ -73,7 +73,7 @@ DatabaseContext CreateContext() return null; } - using var context = CreateContext(); + await using var context = CreateContext(); await context.Database.EnsureDeletedAsync(); await context.Database.MigrateAsync(default); From 4471391b96f0bb72d6c9486ec3179d88591a4a17 Mon Sep 17 00:00:00 2001 From: Dominion Date: Wed, 14 Jun 2023 03:11:41 -0400 Subject: [PATCH 06/33] ValueTask Tgstation.Server.Client --- .../AdministrationClient.cs | 10 +- src/Tgstation.Server.Client/ApiClient.cs | 105 +++++++++++++----- .../Components/ByondClient.cs | 8 +- .../Components/ChatBotsClient.cs | 10 +- .../Components/ConfigurationClient.cs | 10 +- .../Components/DreamDaemonClient.cs | 12 +- .../Components/DreamMakerClient.cs | 10 +- .../Components/IByondClient.cs | 16 +-- .../Components/IChatBotsClient.cs | 20 ++-- .../Components/IConfigurationClient.cs | 20 ++-- .../Components/IDreamDaemonClient.cs | 22 ++-- .../Components/IDreamMakerClient.cs | 20 ++-- .../IInstancePermissionSetClient.cs | 24 ++-- .../Components/IJobsClient.cs | 16 +-- .../Components/IRepositoryClient.cs | 16 +-- .../Components/InstancePermissionSetClient.cs | 12 +- .../Components/JobsClient.cs | 8 +- .../Components/RepositoryClient.cs | 8 +- .../IAdministrationClient.cs | 20 ++-- src/Tgstation.Server.Client/IApiClient.cs | 76 ++++++------- .../IInstanceManagerClient.cs | 24 ++-- src/Tgstation.Server.Client/IRequestLogger.cs | 8 +- src/Tgstation.Server.Client/IServerClient.cs | 2 +- .../IServerClientFactory.cs | 12 +- .../IUserGroupsClient.cs | 20 ++-- src/Tgstation.Server.Client/IUsersClient.cs | 20 ++-- .../InstanceManagerClient.cs | 12 +- .../PaginatedClient.cs | 6 +- src/Tgstation.Server.Client/ServerClient.cs | 2 +- .../ServerClientFactory.cs | 10 +- .../UserGroupsClient.cs | 10 +- src/Tgstation.Server.Client/UsersClient.cs | 10 +- .../Components/TestDreamDaemonClient.cs | 5 +- .../TestApiClient.cs | 2 +- .../Byond/TestPosixByondInstaller.cs | 6 +- .../Database/TestDatabaseContextFactory.cs | 2 +- .../Swarm/TestableSwarmNode.cs | 5 +- tests/Tgstation.Server.Tests/ApiAssert.cs | 38 ------- .../Live/AdministrationTest.cs | 5 +- .../Tgstation.Server.Tests/Live/ApiAssert.cs | 62 +++++++++++ .../Live/Instance/ByondTest.cs | 9 +- .../Live/Instance/ChatTest.cs | 14 ++- .../Live/Instance/DeploymentTest.cs | 31 +++--- .../Live/Instance/RepositoryTest.cs | 6 +- .../Live/Instance/WatchdogTest.cs | 14 +-- .../Live/InstanceManagerTest.cs | 23 ++-- .../Live/RateLimitRetryingApiClient.cs | 2 +- .../Live/RawRequestTests.cs | 2 +- .../Live/TestLiveServer.cs | 28 +++-- .../Tgstation.Server.Tests/Live/UsersTest.cs | 31 +++--- 50 files changed, 473 insertions(+), 391 deletions(-) delete mode 100644 tests/Tgstation.Server.Tests/ApiAssert.cs create mode 100644 tests/Tgstation.Server.Tests/Live/ApiAssert.cs diff --git a/src/Tgstation.Server.Client/AdministrationClient.cs b/src/Tgstation.Server.Client/AdministrationClient.cs index 3f6bb7d6617..8bf796b68fa 100644 --- a/src/Tgstation.Server.Client/AdministrationClient.cs +++ b/src/Tgstation.Server.Client/AdministrationClient.cs @@ -24,10 +24,10 @@ public AdministrationClient(IApiClient apiClient) } /// - public Task Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.Administration, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.Administration, cancellationToken); /// - public async Task Update( + public async ValueTask Update( ServerUpdateRequest updateRequest, Stream? zipFileStream, CancellationToken cancellationToken) @@ -50,14 +50,14 @@ public async Task Update( } /// - public Task Restart(CancellationToken cancellationToken) => ApiClient.Delete(Routes.Administration, cancellationToken); + public ValueTask Restart(CancellationToken cancellationToken) => ApiClient.Delete(Routes.Administration, cancellationToken); /// - public Task> ListLogs(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> ListLogs(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.Logs, null, cancellationToken); /// - public async Task> GetLog(LogFileResponse logFile, CancellationToken cancellationToken) + public async ValueTask> GetLog(LogFileResponse logFile, CancellationToken cancellationToken) { var resultFile = await ApiClient.Read( Routes.Logs + Routes.SanitizeGetPath( diff --git a/src/Tgstation.Server.Client/ApiClient.cs b/src/Tgstation.Server.Client/ApiClient.cs index ae10ac62afc..02dab56be6e 100644 --- a/src/Tgstation.Server.Client/ApiClient.cs +++ b/src/Tgstation.Server.Client/ApiClient.cs @@ -20,6 +20,7 @@ using Tgstation.Server.Api; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Response; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Common.Http; namespace Tgstation.Server.Client @@ -168,61 +169,61 @@ public void Dispose() } /// - public Task Create(string route, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Put, null, false, cancellationToken); + public ValueTask Create(string route, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Put, null, false, cancellationToken); /// - public Task Read(string route, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Get, null, false, cancellationToken); + public ValueTask Read(string route, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Get, null, false, cancellationToken); /// - public Task Update(string route, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Post, null, false, cancellationToken); + public ValueTask Update(string route, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Post, null, false, cancellationToken); /// - public Task Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Post, null, false, cancellationToken); + public ValueTask Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Post, null, false, cancellationToken); /// - public Task Patch(string route, CancellationToken cancellationToken) => RunRequest(route, null, HttpPatch, null, false, cancellationToken); + public ValueTask Patch(string route, CancellationToken cancellationToken) => RunRequest(route, HttpPatch, null, false, cancellationToken); /// - public Task Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Post, null, false, cancellationToken); + public ValueTask Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunResultlessRequest(route, body, HttpMethod.Post, null, false, cancellationToken); /// - public Task Create(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Put, null, false, cancellationToken); + public ValueTask Create(string route, TBody body, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Put, null, false, cancellationToken); /// - public Task Delete(string route, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Delete, null, false, cancellationToken); + public ValueTask Delete(string route, CancellationToken cancellationToken) => RunRequest(route, HttpMethod.Delete, null, false, cancellationToken); /// - public Task Create(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Put, instanceId, false, cancellationToken); + public ValueTask Create(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Put, instanceId, false, cancellationToken); /// - public Task Read(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Get, instanceId, false, cancellationToken); + public ValueTask Read(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Get, instanceId, false, cancellationToken); /// - public Task Update(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Post, instanceId, false, cancellationToken); + public ValueTask Update(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Post, instanceId, false, cancellationToken); /// - public Task Delete(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Delete, instanceId, false, cancellationToken); + public ValueTask Delete(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, HttpMethod.Delete, instanceId, false, cancellationToken); /// - public Task Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken); + public async ValueTask Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => await RunRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken); /// - public Task Delete(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Delete, instanceId, false, cancellationToken); + public ValueTask Delete(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, null, HttpMethod.Delete, instanceId, false, cancellationToken); /// - public Task Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken); + public ValueTask Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class => RunRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken); /// - public Task Create(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Put, instanceId, false, cancellationToken); + public ValueTask Create(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Put, instanceId, false, cancellationToken); /// - public Task Patch(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpPatch, instanceId, false, cancellationToken); + public ValueTask Patch(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpPatch, instanceId, false, cancellationToken); /// public void AddRequestLogger(IRequestLogger requestLogger) => requestLoggers.Add(requestLogger ?? throw new ArgumentNullException(nameof(requestLogger))); /// - public Task Download(FileTicketResponse ticket, CancellationToken cancellationToken) + public ValueTask Download(FileTicketResponse ticket, CancellationToken cancellationToken) { if (ticket == null) throw new ArgumentNullException(nameof(ticket)); @@ -237,7 +238,7 @@ public Task Download(FileTicketResponse ticket, CancellationToken cancel } /// - public async Task Upload(FileTicketResponse ticket, Stream? uploadStream, CancellationToken cancellationToken) + public async ValueTask Upload(FileTicketResponse ticket, Stream? uploadStream, CancellationToken cancellationToken) { if (ticket == null) throw new ArgumentNullException(nameof(ticket)); @@ -280,8 +281,8 @@ await RunRequest( /// The optional instance for the request. /// If this is a token refresh operation. /// The for the operation. - /// A resulting in the response on success. - protected virtual async Task RunRequest( + /// A resulting in the response on success. + protected virtual async ValueTask RunRequest( string route, HttpContent? content, HttpMethod method, @@ -316,7 +317,7 @@ protected virtual async Task RunRequest( if (fileDownload) request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Octet)); - await Task.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken))).ConfigureAwait(false); + await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken)), requestLoggers.Count).ConfigureAwait(false); response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); } @@ -329,7 +330,7 @@ protected virtual async Task RunRequest( try { - await Task.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken))).ConfigureAwait(false); + await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken)), requestLoggers.Count).ConfigureAwait(false); // just stream if (fileDownload && response.IsSuccessStatusCode) @@ -373,8 +374,8 @@ protected virtual async Task RunRequest( /// Attempt to refresh the bearer token in the . /// /// The for the operation. - /// A resulting in if the refresh was successful, otherwise. - async Task RefreshToken(CancellationToken cancellationToken) + /// A resulting in if the refresh was successful, otherwise. + async ValueTask RefreshToken(CancellationToken cancellationToken) { if (tokenRefreshHeaders == null) return false; @@ -412,8 +413,8 @@ async Task RefreshToken(CancellationToken cancellationToken) /// The optional instance for the request. /// If this is a token refresh operation. /// The for the operation. - /// A resulting in the response on success. - async Task RunRequest( + /// A resulting in the response on success. + async ValueTask RunRequest( string route, TBody? body, HttpMethod method, @@ -439,5 +440,55 @@ async Task RunRequest( cancellationToken) .ConfigureAwait(false); } + + /// + /// Main request method. + /// + /// The body . + /// The route to run. + /// The body of the request. + /// The method of the request. + /// The optional instance for the request. + /// If this is a token refresh operation. + /// The for the operation. + /// A resulting in the response on success. + async ValueTask RunResultlessRequest( + string route, + TBody? body, + HttpMethod method, + long? instanceId, + bool tokenRefresh, + CancellationToken cancellationToken) + where TBody : class + => await RunRequest( + route, + body, + method, + instanceId, + tokenRefresh, + cancellationToken); + + /// + /// Main request method. + /// + /// The route to run. + /// The method of the request. + /// The optional instance for the request. + /// If this is a token refresh operation. + /// The for the operation. + /// A resulting in the response on success. + ValueTask RunRequest( + string route, + HttpMethod method, + long? instanceId, + bool tokenRefresh, + CancellationToken cancellationToken) + => RunResultlessRequest( + route, + null, + method, + instanceId, + tokenRefresh, + cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/ByondClient.cs b/src/Tgstation.Server.Client/Components/ByondClient.cs index c167af06657..4a35067a22f 100644 --- a/src/Tgstation.Server.Client/Components/ByondClient.cs +++ b/src/Tgstation.Server.Client/Components/ByondClient.cs @@ -31,18 +31,18 @@ public ByondClient(IApiClient apiClient, Instance instance) } /// - public Task ActiveVersion(CancellationToken cancellationToken) => ApiClient.Read(Routes.Byond, instance.Id!.Value, cancellationToken); + public ValueTask ActiveVersion(CancellationToken cancellationToken) => ApiClient.Read(Routes.Byond, instance.Id!.Value, cancellationToken); /// - public Task DeleteVersion(ByondVersionDeleteRequest deleteRequest, CancellationToken cancellationToken) + public ValueTask DeleteVersion(ByondVersionDeleteRequest deleteRequest, CancellationToken cancellationToken) => ApiClient.Delete(Routes.Byond, deleteRequest, instance.Id!.Value, cancellationToken); /// - public Task> InstalledVersions(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> InstalledVersions(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.Byond), instance.Id, cancellationToken); /// - public async Task SetActiveVersion(ByondVersionRequest installRequest, Stream? zipFileStream, CancellationToken cancellationToken) + public async ValueTask SetActiveVersion(ByondVersionRequest installRequest, Stream? zipFileStream, CancellationToken cancellationToken) { if (installRequest == null) throw new ArgumentNullException(nameof(installRequest)); diff --git a/src/Tgstation.Server.Client/Components/ChatBotsClient.cs b/src/Tgstation.Server.Client/Components/ChatBotsClient.cs index d53b0044acd..718964fe452 100644 --- a/src/Tgstation.Server.Client/Components/ChatBotsClient.cs +++ b/src/Tgstation.Server.Client/Components/ChatBotsClient.cs @@ -30,19 +30,19 @@ public ChatBotsClient(IApiClient apiClient, Instance instance) } /// - public Task Create(ChatBotCreateRequest settings, CancellationToken cancellationToken) => ApiClient.Create(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken); + public ValueTask Create(ChatBotCreateRequest settings, CancellationToken cancellationToken) => ApiClient.Create(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken); /// - public Task Delete(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken); + public ValueTask Delete(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken); /// - public Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.Chat), instance.Id!.Value, cancellationToken); /// - public Task Update(ChatBotUpdateRequest settings, CancellationToken cancellationToken) => ApiClient.Update(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken); + public ValueTask Update(ChatBotUpdateRequest settings, CancellationToken cancellationToken) => ApiClient.Update(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken); /// - public Task GetId(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken); + public ValueTask GetId(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/ConfigurationClient.cs b/src/Tgstation.Server.Client/Components/ConfigurationClient.cs index 581c1ad791c..59848099c06 100644 --- a/src/Tgstation.Server.Client/Components/ConfigurationClient.cs +++ b/src/Tgstation.Server.Client/Components/ConfigurationClient.cs @@ -31,13 +31,13 @@ public ConfigurationClient(IApiClient apiClient, Instance instance) } /// - public Task DeleteEmptyDirectory(IConfigurationFile directory, CancellationToken cancellationToken) => ApiClient.Delete(Routes.Configuration, directory, instance.Id!.Value, cancellationToken); + public ValueTask DeleteEmptyDirectory(IConfigurationFile directory, CancellationToken cancellationToken) => ApiClient.Delete(Routes.Configuration, directory, instance.Id!.Value, cancellationToken); /// - public Task CreateDirectory(IConfigurationFile directory, CancellationToken cancellationToken) => ApiClient.Create(Routes.Configuration, directory, instance.Id!.Value, cancellationToken); + public ValueTask CreateDirectory(IConfigurationFile directory, CancellationToken cancellationToken) => ApiClient.Create(Routes.Configuration, directory, instance.Id!.Value, cancellationToken); /// - public Task> List( + public ValueTask> List( PaginationSettings? paginationSettings, string directory, CancellationToken cancellationToken) @@ -48,7 +48,7 @@ public Task> List( cancellationToken); /// - public async Task> Read(IConfigurationFile file, CancellationToken cancellationToken) + public async ValueTask> Read(IConfigurationFile file, CancellationToken cancellationToken) { if (file == null) throw new ArgumentNullException(nameof(file)); @@ -70,7 +70,7 @@ public async Task> Read(IConfigurationF } /// - public async Task Write(ConfigurationFileRequest file, Stream uploadStream, CancellationToken cancellationToken) + public async ValueTask Write(ConfigurationFileRequest file, Stream uploadStream, CancellationToken cancellationToken) { long initialStreamPosition = 0; MemoryStream? memoryStream = null; diff --git a/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs b/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs index 28b1b56b4ea..cf4eb3ea874 100644 --- a/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs +++ b/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs @@ -34,21 +34,21 @@ public DreamDaemonClient(IApiClient apiClient, Instance instance) } /// - public Task Shutdown(CancellationToken cancellationToken) => apiClient.Delete(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); + public ValueTask Shutdown(CancellationToken cancellationToken) => apiClient.Delete(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); /// - public Task Start(CancellationToken cancellationToken) => apiClient.Create(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); + public ValueTask Start(CancellationToken cancellationToken) => apiClient.Create(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); /// - public Task Restart(CancellationToken cancellationToken) => apiClient.Patch(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); + public ValueTask Restart(CancellationToken cancellationToken) => apiClient.Patch(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); /// - public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => apiClient.Read(Routes.DreamDaemon, instance.Id!.Value, cancellationToken); /// - public Task Update(DreamDaemonRequest dreamDaemon, CancellationToken cancellationToken) => apiClient.Update(Routes.DreamDaemon, dreamDaemon ?? throw new ArgumentNullException(nameof(dreamDaemon)), instance.Id!.Value, cancellationToken); + public ValueTask Update(DreamDaemonRequest dreamDaemon, CancellationToken cancellationToken) => apiClient.Update(Routes.DreamDaemon, dreamDaemon ?? throw new ArgumentNullException(nameof(dreamDaemon)), instance.Id!.Value, cancellationToken); /// - public Task CreateDump(CancellationToken cancellationToken) => apiClient.Patch(Routes.Diagnostics, instance.Id!.Value, cancellationToken); + public ValueTask CreateDump(CancellationToken cancellationToken) => apiClient.Patch(Routes.Diagnostics, instance.Id!.Value, cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/DreamMakerClient.cs b/src/Tgstation.Server.Client/Components/DreamMakerClient.cs index 11bacc51dbf..32cde4b89c1 100644 --- a/src/Tgstation.Server.Client/Components/DreamMakerClient.cs +++ b/src/Tgstation.Server.Client/Components/DreamMakerClient.cs @@ -30,19 +30,19 @@ public DreamMakerClient(IApiClient apiClient, Instance instance) } /// - public Task Compile(CancellationToken cancellationToken) => ApiClient.Create(Routes.DreamMaker, instance.Id!.Value, cancellationToken); + public ValueTask Compile(CancellationToken cancellationToken) => ApiClient.Create(Routes.DreamMaker, instance.Id!.Value, cancellationToken); /// - public Task GetCompileJob(EntityId compileJob, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.DreamMaker, compileJob?.Id ?? throw new ArgumentNullException(nameof(compileJob))), instance.Id!.Value, cancellationToken); + public ValueTask GetCompileJob(EntityId compileJob, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.DreamMaker, compileJob?.Id ?? throw new ArgumentNullException(nameof(compileJob))), instance.Id!.Value, cancellationToken); /// - public Task> ListCompileJobs(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> ListCompileJobs(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.DreamMaker), instance.Id!.Value, cancellationToken); /// - public Task Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.DreamMaker, instance.Id!.Value, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.DreamMaker, instance.Id!.Value, cancellationToken); /// - public Task Update(DreamMakerRequest dreamMaker, CancellationToken cancellationToken) => ApiClient.Update(Routes.DreamMaker, dreamMaker ?? throw new ArgumentNullException(nameof(dreamMaker)), instance.Id!.Value, cancellationToken); + public ValueTask Update(DreamMakerRequest dreamMaker, CancellationToken cancellationToken) => ApiClient.Update(Routes.DreamMaker, dreamMaker ?? throw new ArgumentNullException(nameof(dreamMaker)), instance.Id!.Value, cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IByondClient.cs b/src/Tgstation.Server.Client/Components/IByondClient.cs index 0b2c8ddb1ea..bde6e04535c 100644 --- a/src/Tgstation.Server.Client/Components/IByondClient.cs +++ b/src/Tgstation.Server.Client/Components/IByondClient.cs @@ -17,16 +17,16 @@ public interface IByondClient /// Get the active information. /// /// The for the operation. - /// A resulting in the active information. - Task ActiveVersion(CancellationToken cancellationToken); + /// A resulting in the active information. + ValueTask ActiveVersion(CancellationToken cancellationToken); /// /// Get all installed s. /// /// The optional for the operation. /// The for the operation. - /// A resulting in an of installed s. - Task> InstalledVersions(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in an of installed s. + ValueTask> InstalledVersions(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Updates the active BYOND version. @@ -34,15 +34,15 @@ public interface IByondClient /// The . /// The for the .zip file if is . Will be ignored if it is . /// The for the operation. - /// A resulting in the updated information. - Task SetActiveVersion(ByondVersionRequest installRequest, Stream? zipFileStream, CancellationToken cancellationToken); + /// A resulting in the updated information. + ValueTask SetActiveVersion(ByondVersionRequest installRequest, Stream? zipFileStream, CancellationToken cancellationToken); /// /// Starts a jobs to delete a specific BYOND version. /// /// The specifying the version to delete. /// The for the operation. - /// A resulting in the for the delete job. - Task DeleteVersion(ByondVersionDeleteRequest deleteRequest, CancellationToken cancellationToken); + /// A resulting in the for the delete job. + ValueTask DeleteVersion(ByondVersionDeleteRequest deleteRequest, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IChatBotsClient.cs b/src/Tgstation.Server.Client/Components/IChatBotsClient.cs index 664dcb14ac5..88534b8d66f 100644 --- a/src/Tgstation.Server.Client/Components/IChatBotsClient.cs +++ b/src/Tgstation.Server.Client/Components/IChatBotsClient.cs @@ -18,39 +18,39 @@ public interface IChatBotsClient /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of the s. - Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of the s. + ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Create a chat bot. /// /// The . /// The for the operation. - /// A resulting in the of the newly created chat bot. - Task Create(ChatBotCreateRequest settings, CancellationToken cancellationToken); + /// A resulting in the of the newly created chat bot. + ValueTask Create(ChatBotCreateRequest settings, CancellationToken cancellationToken); /// /// Updates a chat bot's setttings. /// /// The . /// The for the operation. - /// A resulting in the updated chat bot's . - Task Update(ChatBotUpdateRequest settings, CancellationToken cancellationToken); + /// A resulting in the updated chat bot's . + ValueTask Update(ChatBotUpdateRequest settings, CancellationToken cancellationToken); /// /// Get a specific chat bot's settings. /// /// The of the chat bot to get. /// The for the operation. - /// A resulting in the . - Task GetId(EntityId settingsId, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask GetId(EntityId settingsId, CancellationToken cancellationToken); /// /// Delete a chat bot. /// /// The of the chat bot to delete. /// The for the operation. - /// A representing the running operation. - Task Delete(EntityId settingsId, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Delete(EntityId settingsId, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IConfigurationClient.cs b/src/Tgstation.Server.Client/Components/IConfigurationClient.cs index 07199796b14..99700d6d14e 100644 --- a/src/Tgstation.Server.Client/Components/IConfigurationClient.cs +++ b/src/Tgstation.Server.Client/Components/IConfigurationClient.cs @@ -21,8 +21,8 @@ public interface IConfigurationClient /// The optional for the operation. /// The path to the directory to list files in. /// The for the operation. - /// A of s in the . - Task> List( + /// A of s in the . + ValueTask> List( PaginationSettings? paginationSettings, string directory, CancellationToken cancellationToken); @@ -32,8 +32,8 @@ Task> List( /// /// The file to read. /// The for the operation. - /// A resulting in a containing the and downloaded . - Task> Read(IConfigurationFile file, CancellationToken cancellationToken); + /// A resulting in a containing the and downloaded . + ValueTask> Read(IConfigurationFile file, CancellationToken cancellationToken); /// /// Overwrite a . @@ -41,23 +41,23 @@ Task> List( /// The . /// The of uploaded data. If , a delete will be attempted. /// The for the operation. - /// A resulting in the new . - Task Write(ConfigurationFileRequest file, Stream uploadStream, CancellationToken cancellationToken); + /// A resulting in the new . + ValueTask Write(ConfigurationFileRequest file, Stream uploadStream, CancellationToken cancellationToken); /// /// Delete an empty . /// /// The representing the directory to delete. /// The for the operation. - /// A representing the running operation. - Task DeleteEmptyDirectory(IConfigurationFile directory, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask DeleteEmptyDirectory(IConfigurationFile directory, CancellationToken cancellationToken); /// /// Creates an empty . /// /// The representing the directory to create. /// The for the operation. - /// A resulting in the new . - Task CreateDirectory(IConfigurationFile directory, CancellationToken cancellationToken); + /// A resulting in the new . + ValueTask CreateDirectory(IConfigurationFile directory, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IDreamDaemonClient.cs b/src/Tgstation.Server.Client/Components/IDreamDaemonClient.cs index f636e4dc8fa..7a7a6ead7cf 100644 --- a/src/Tgstation.Server.Client/Components/IDreamDaemonClient.cs +++ b/src/Tgstation.Server.Client/Components/IDreamDaemonClient.cs @@ -15,43 +15,43 @@ public interface IDreamDaemonClient /// Get the represented by the . /// /// The for the operation. - /// A resulting in the information. - Task Read(CancellationToken cancellationToken); + /// A resulting in the information. + ValueTask Read(CancellationToken cancellationToken); /// /// Start . /// /// The for the operation. /// A resulting in the of the running operation. - Task Start(CancellationToken cancellationToken); + ValueTask Start(CancellationToken cancellationToken); /// /// Restart . /// /// The for the operation. - /// A resulting in the of the running operation. - Task Restart(CancellationToken cancellationToken); + /// A resulting in the of the running operation. + ValueTask Restart(CancellationToken cancellationToken); /// /// Shutdown . /// /// The for the operation. - /// A resulting in the information. - Task Shutdown(CancellationToken cancellationToken); + /// A resulting in the information. + ValueTask Shutdown(CancellationToken cancellationToken); /// /// Update . This may trigger a . /// /// The . /// The for the operation. - /// A resulting in the information. - Task Update(DreamDaemonRequest dreamDaemon, CancellationToken cancellationToken); + /// A resulting in the information. + ValueTask Update(DreamDaemonRequest dreamDaemon, CancellationToken cancellationToken); /// /// Start a job to create a process dump of the active DreamDaemon executable. /// /// The for the operation. - /// A resulting in the of the running operation. - Task CreateDump(CancellationToken cancellationToken); + /// A resulting in the of the running operation. + ValueTask CreateDump(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs b/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs index 0c31b602401..f40067456c5 100644 --- a/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs +++ b/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs @@ -17,38 +17,38 @@ public interface IDreamMakerClient /// Get the . /// /// The for the operation. - /// A resulting in the . - Task Read(CancellationToken cancellationToken); + /// A resulting in the . + ValueTask Read(CancellationToken cancellationToken); /// /// Updates the . /// /// The to update. /// The for the operation. - /// A representing the running operation. - Task Update(DreamMakerRequest dreamMaker, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Update(DreamMakerRequest dreamMaker, CancellationToken cancellationToken); /// /// Compile the current repository revision. /// /// The for the operation. - /// A resulting in the for the compile. - Task Compile(CancellationToken cancellationToken); + /// A resulting in the for the compile. + ValueTask Compile(CancellationToken cancellationToken); /// /// Gets the s for the instance. /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of s. - Task> ListCompileJobs(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of s. + ValueTask> ListCompileJobs(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Get a . /// /// The 's to get. /// The for the operation. - /// A resulting in the . - Task GetCompileJob(EntityId compileJob, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask GetCompileJob(EntityId compileJob, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IInstancePermissionSetClient.cs b/src/Tgstation.Server.Client/Components/IInstancePermissionSetClient.cs index 2f7d1b73a1b..e4aac4a07ef 100644 --- a/src/Tgstation.Server.Client/Components/IInstancePermissionSetClient.cs +++ b/src/Tgstation.Server.Client/Components/IInstancePermissionSetClient.cs @@ -17,47 +17,47 @@ public interface IInstancePermissionSetClient /// Get the instance permission sets associated with the logged on user. /// /// The for the operation. - /// A resulting in the associated with the logged on user. - Task Read(CancellationToken cancellationToken); + /// A resulting in the associated with the logged on user. + ValueTask Read(CancellationToken cancellationToken); /// /// Get a specific . /// /// The . /// The for the operation. - /// A resulting in the requested . - Task GetId(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken); + /// A resulting in the requested . + ValueTask GetId(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken); /// /// Get the instance permission sets in the instance. /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of s in the instance. - Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of s in the instance. + ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Update a . /// /// The . /// The for the operation. - /// A representing the running operation. - Task Update(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Update(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken); /// /// Create a . /// /// The . /// The for the operation. - /// A reulting in the new . - Task Create(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken); + /// A reulting in the new . + ValueTask Create(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken); /// /// Delete a . /// /// The to delete. /// The for the operation. - /// A representing the running operation. - Task Delete(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Delete(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IJobsClient.cs b/src/Tgstation.Server.Client/Components/IJobsClient.cs index 108b5aab776..79bbd952a25 100644 --- a/src/Tgstation.Server.Client/Components/IJobsClient.cs +++ b/src/Tgstation.Server.Client/Components/IJobsClient.cs @@ -17,31 +17,31 @@ public interface IJobsClient /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of the s in the . - Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of the s in the . + ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// List the active s in the . /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of the active s in the . - Task> ListActive(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of the active s in the . + ValueTask> ListActive(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Get a . /// /// The 's to get. /// The for the operation. - /// A resulting in the . - Task GetId(EntityId job, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask GetId(EntityId job, CancellationToken cancellationToken); /// /// Cancels a . /// /// The to cancel. /// The for the operation. - /// A representing the running operation. - Task Cancel(JobResponse job, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Cancel(JobResponse job, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IRepositoryClient.cs b/src/Tgstation.Server.Client/Components/IRepositoryClient.cs index a8495e1efd2..9d3bef806cf 100644 --- a/src/Tgstation.Server.Client/Components/IRepositoryClient.cs +++ b/src/Tgstation.Server.Client/Components/IRepositoryClient.cs @@ -15,30 +15,30 @@ public interface IRepositoryClient /// Get the repository's current status. /// /// The for the operation. - /// A resulting in the . - Task Read(CancellationToken cancellationToken); + /// A resulting in the . + ValueTask Read(CancellationToken cancellationToken); /// /// Update the repository. /// /// The . /// The for the operation. - /// A resulting in the . - Task Update(RepositoryUpdateRequest repository, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask Update(RepositoryUpdateRequest repository, CancellationToken cancellationToken); /// /// Clones a . /// /// The . /// The for the operation. - /// A resulting in the /. - Task Clone(RepositoryCreateRequest repository, CancellationToken cancellationToken); + /// A resulting in the /. + ValueTask Clone(RepositoryCreateRequest repository, CancellationToken cancellationToken); /// /// Deletes the repository. /// /// The for the operation. - /// A resulting in the . - Task Delete(CancellationToken cancellationToken); + /// A resulting in the . + ValueTask Delete(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/InstancePermissionSetClient.cs b/src/Tgstation.Server.Client/Components/InstancePermissionSetClient.cs index 1403ac073a1..8569da489f9 100644 --- a/src/Tgstation.Server.Client/Components/InstancePermissionSetClient.cs +++ b/src/Tgstation.Server.Client/Components/InstancePermissionSetClient.cs @@ -31,10 +31,10 @@ public InstancePermissionSetClient(IApiClient apiClient, Instance instance) } /// - public Task Create(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Create(Routes.InstancePermissionSet, instancePermissionSet ?? throw new ArgumentNullException(nameof(instancePermissionSet)), instance.Id!.Value, cancellationToken); + public ValueTask Create(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Create(Routes.InstancePermissionSet, instancePermissionSet ?? throw new ArgumentNullException(nameof(instancePermissionSet)), instance.Id!.Value, cancellationToken); /// - public Task Delete(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Delete( + public ValueTask Delete(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Delete( Routes.SetID( Routes.InstancePermissionSet, instancePermissionSet.PermissionSetId), @@ -42,13 +42,13 @@ public Task Delete(InstancePermissionSet instancePermissionSet, CancellationToke cancellationToken); /// - public Task Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.InstancePermissionSet, instance.Id!.Value, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.InstancePermissionSet, instance.Id!.Value, cancellationToken); /// - public Task Update(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Update(Routes.InstancePermissionSet, instancePermissionSet ?? throw new ArgumentNullException(nameof(instancePermissionSet)), instance.Id!.Value, cancellationToken); + public ValueTask Update(InstancePermissionSetRequest instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Update(Routes.InstancePermissionSet, instancePermissionSet ?? throw new ArgumentNullException(nameof(instancePermissionSet)), instance.Id!.Value, cancellationToken); /// - public Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged( paginationSettings, Routes.ListRoute(Routes.InstancePermissionSet), @@ -56,6 +56,6 @@ public Task> List(PaginationSetting cancellationToken); /// - public Task GetId(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.InstancePermissionSet, instancePermissionSet?.PermissionSetId ?? throw new ArgumentNullException(nameof(instancePermissionSet))), instance.Id!.Value, cancellationToken); + public ValueTask GetId(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.InstancePermissionSet, instancePermissionSet?.PermissionSetId ?? throw new ArgumentNullException(nameof(instancePermissionSet))), instance.Id!.Value, cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/JobsClient.cs b/src/Tgstation.Server.Client/Components/JobsClient.cs index c1435768739..4d02ce95c45 100644 --- a/src/Tgstation.Server.Client/Components/JobsClient.cs +++ b/src/Tgstation.Server.Client/Components/JobsClient.cs @@ -29,17 +29,17 @@ public JobsClient(IApiClient apiClient, Instance instance) } /// - public Task Cancel(JobResponse job, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id!.Value, cancellationToken); + public ValueTask Cancel(JobResponse job, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id!.Value, cancellationToken); /// - public Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.Jobs), instance.Id!.Value, cancellationToken); /// - public Task> ListActive(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> ListActive(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.Jobs, instance.Id!.Value, cancellationToken); /// - public Task GetId(EntityId job, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id!.Value, cancellationToken); + public ValueTask GetId(EntityId job, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id!.Value, cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/RepositoryClient.cs b/src/Tgstation.Server.Client/Components/RepositoryClient.cs index a5e47656c56..124f1ec5b28 100644 --- a/src/Tgstation.Server.Client/Components/RepositoryClient.cs +++ b/src/Tgstation.Server.Client/Components/RepositoryClient.cs @@ -34,15 +34,15 @@ public RepositoryClient(IApiClient apiClient, Instance instance) } /// - public Task Clone(RepositoryCreateRequest repository, CancellationToken cancellationToken) => apiClient.Create(Routes.Repository, repository, instance.Id!.Value, cancellationToken); + public ValueTask Clone(RepositoryCreateRequest repository, CancellationToken cancellationToken) => apiClient.Create(Routes.Repository, repository, instance.Id!.Value, cancellationToken); /// - public Task Delete(CancellationToken cancellationToken) => apiClient.Delete(Routes.Repository, instance.Id!.Value, cancellationToken); + public ValueTask Delete(CancellationToken cancellationToken) => apiClient.Delete(Routes.Repository, instance.Id!.Value, cancellationToken); /// - public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.Repository, instance.Id!.Value, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => apiClient.Read(Routes.Repository, instance.Id!.Value, cancellationToken); /// - public Task Update(RepositoryUpdateRequest repository, CancellationToken cancellationToken) => apiClient.Update(Routes.Repository, repository ?? throw new ArgumentNullException(nameof(repository)), instance.Id!.Value, cancellationToken); + public ValueTask Update(RepositoryUpdateRequest repository, CancellationToken cancellationToken) => apiClient.Update(Routes.Repository, repository ?? throw new ArgumentNullException(nameof(repository)), instance.Id!.Value, cancellationToken); } } diff --git a/src/Tgstation.Server.Client/IAdministrationClient.cs b/src/Tgstation.Server.Client/IAdministrationClient.cs index ec663961349..38d08983450 100644 --- a/src/Tgstation.Server.Client/IAdministrationClient.cs +++ b/src/Tgstation.Server.Client/IAdministrationClient.cs @@ -18,8 +18,8 @@ public interface IAdministrationClient /// Get the represented by the . /// /// The for the operation. - /// A resulting in the represented by the . - Task Read(CancellationToken cancellationToken); + /// A resulting in the represented by the . + ValueTask Read(CancellationToken cancellationToken); /// /// Updates the setttings. @@ -27,30 +27,30 @@ public interface IAdministrationClient /// The . /// The for the .zip file if is . Will be ignored if it is . /// The for the operation. - /// A resulting in the echoed . - Task Update(ServerUpdateRequest updateRequest, Stream? zipFileStream, CancellationToken cancellationToken); + /// A resulting in the echoed . + ValueTask Update(ServerUpdateRequest updateRequest, Stream? zipFileStream, CancellationToken cancellationToken); /// /// Restarts the TGS server. /// /// The for the operation. - /// A representing the running operation. - Task Restart(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Restart(CancellationToken cancellationToken); /// /// Lists the log files available for download. /// /// The optional for the operation. /// The for the operation. - /// A resulting in an of metadata. - Task> ListLogs(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in an of metadata. + ValueTask> ListLogs(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Download a given . /// /// The to download. /// The for the operation. - /// A resulting a containing the downloaded and associated . - Task> GetLog(LogFileResponse logFile, CancellationToken cancellationToken); + /// A resulting a containing the downloaded and associated . + ValueTask> GetLog(LogFileResponse logFile, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/IApiClient.cs b/src/Tgstation.Server.Client/IApiClient.cs index 7758e9aefe1..6471cf040ae 100644 --- a/src/Tgstation.Server.Client/IApiClient.cs +++ b/src/Tgstation.Server.Client/IApiClient.cs @@ -43,8 +43,8 @@ interface IApiClient : IDisposable /// The server route to make the request to. /// The request body. /// The for the operation. - /// A resulting in the response body as a . - Task Create(string route, TBody body, CancellationToken cancellationToken) where TBody : class; + /// A resulting in the response body as a . + ValueTask Create(string route, TBody body, CancellationToken cancellationToken) where TBody : class; /// /// Run an HTTP PUT request. @@ -52,8 +52,8 @@ interface IApiClient : IDisposable /// The type of the response body. /// The server route to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Create(string route, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Create(string route, CancellationToken cancellationToken); /// /// Run an HTTP GET request. @@ -61,8 +61,8 @@ interface IApiClient : IDisposable /// The type of the response body. /// The server route to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Read(string route, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Read(string route, CancellationToken cancellationToken); /// /// Run an HTTP POST request. @@ -72,8 +72,8 @@ interface IApiClient : IDisposable /// The server route to make the request to. /// The request body. /// The for the operation. - /// A resulting in the response body as a . - Task Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class; + /// A resulting in the response body as a . + ValueTask Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class; /// /// Run an HTTP POST request. @@ -81,8 +81,8 @@ interface IApiClient : IDisposable /// The type of the response body. /// The server route to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Update(string route, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Update(string route, CancellationToken cancellationToken); /// /// Run an HTTP POST request. @@ -91,24 +91,24 @@ interface IApiClient : IDisposable /// The server route to make the request to. /// The request body. /// The for the operation. - /// A representing the running operation. - Task Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class; + /// A representing the running operation. + ValueTask Update(string route, TBody body, CancellationToken cancellationToken) where TBody : class; /// /// Run an HTTP PATCH request. /// /// The server route to make the request to. /// The for the operation. - /// A representing the running operation. - Task Patch(string route, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Patch(string route, CancellationToken cancellationToken); /// /// Run an HTTP DELETE request. /// /// The server route to make the request to. /// The for the operation. - /// A representing the running operation. - Task Delete(string route, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Delete(string route, CancellationToken cancellationToken); /// /// Run an HTTP PUT request. @@ -119,8 +119,8 @@ interface IApiClient : IDisposable /// The request body. /// The instance to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Create( + /// A resulting in the response body as a . + ValueTask Create( string route, TBody body, long instanceId, @@ -134,8 +134,8 @@ Task Create( /// The server route to make the request to. /// The instance to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Create(string route, long instanceId, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Create(string route, long instanceId, CancellationToken cancellationToken); /// /// Run an HTTP PATCH request. @@ -144,8 +144,8 @@ Task Create( /// The server route to make the request to. /// The instance to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Patch(string route, long instanceId, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Patch(string route, long instanceId, CancellationToken cancellationToken); /// /// Run an HTTP GET request. @@ -154,8 +154,8 @@ Task Create( /// The server route to make the request to. /// The instance to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Read(string route, long instanceId, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Read(string route, long instanceId, CancellationToken cancellationToken); /// /// Run an HTTP POST request. @@ -166,8 +166,8 @@ Task Create( /// The request body. /// The instance to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Update( + /// A resulting in the response body as a . + ValueTask Update( string route, TBody body, long instanceId, @@ -180,8 +180,8 @@ Task Update( /// The server route to make the request to. /// The instance to make the request to. /// The for the operation. - /// A representing the running operation. - Task Delete(string route, long instanceId, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Delete(string route, long instanceId, CancellationToken cancellationToken); /// /// Run an HTTP DELETE request. @@ -191,8 +191,8 @@ Task Update( /// The request body. /// The instance to make the request to. /// The for the operation. - /// A representing the running operation. - Task Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class; + /// A representing the running operation. + ValueTask Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class; /// /// Run an HTTP DELETE request. @@ -201,8 +201,8 @@ Task Update( /// The server route to make the request to. /// The instance to make the request to. /// The for the operation. - /// A resulting in the response body as a . - Task Delete(string route, long instanceId, CancellationToken cancellationToken); + /// A resulting in the response body as a . + ValueTask Delete(string route, long instanceId, CancellationToken cancellationToken); /// /// Run an HTTP DELETE request. @@ -213,16 +213,16 @@ Task Update( /// The request body. /// The instance to make the request to. /// The for the operation. - /// A representing the running operation. - Task Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class; + /// A representing the running operation. + ValueTask Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class; /// /// Downloads a file for a given . /// /// The to download. /// The for the operation. - /// A resulting in the downloaded . - Task Download(FileTicketResponse ticket, CancellationToken cancellationToken); + /// A resulting in the downloaded . + ValueTask Download(FileTicketResponse ticket, CancellationToken cancellationToken); /// /// Uploads a given for a given . @@ -230,7 +230,7 @@ Task Update( /// The to download. /// The to upload. represents an empty file. /// The for the operation. - /// A representing the running operation. - Task Upload(FileTicketResponse ticket, Stream? uploadStream, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Upload(FileTicketResponse ticket, Stream? uploadStream, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/IInstanceManagerClient.cs b/src/Tgstation.Server.Client/IInstanceManagerClient.cs index 7bf96e0ec7b..a9e29f30fa7 100644 --- a/src/Tgstation.Server.Client/IInstanceManagerClient.cs +++ b/src/Tgstation.Server.Client/IInstanceManagerClient.cs @@ -19,48 +19,48 @@ public interface IInstanceManagerClient /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of all s the user can view. - Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of all s the user can view. + ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Create or attach an . /// /// The . /// The for the operation. - /// A resulting in the created or attached . - Task CreateOrAttach(InstanceCreateRequest instance, CancellationToken cancellationToken); + /// A resulting in the created or attached . + ValueTask CreateOrAttach(InstanceCreateRequest instance, CancellationToken cancellationToken); /// /// Relocates, renamed, and/or on/offlines an . /// /// The . /// The for the operation. - /// A resulting in the updated . - Task Update(InstanceUpdateRequest instance, CancellationToken cancellationToken); + /// A resulting in the updated . + ValueTask Update(InstanceUpdateRequest instance, CancellationToken cancellationToken); /// /// Get a specific . /// /// The to get. /// The for the operation. - /// A resulting in the . - Task GetId(EntityId instance, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask GetId(EntityId instance, CancellationToken cancellationToken); /// /// Deletes an . /// /// The of the to delete. /// The for the operation. - /// A representing the running operation. - Task Detach(EntityId instance, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Detach(EntityId instance, CancellationToken cancellationToken); /// /// Gives the user full permissions on an . /// /// The of the to grant permissions on. /// The for the operation. - /// A representing the running operation. - Task GrantPermissions(EntityId instance, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask GrantPermissions(EntityId instance, CancellationToken cancellationToken); /// /// Create an for a given . diff --git a/src/Tgstation.Server.Client/IRequestLogger.cs b/src/Tgstation.Server.Client/IRequestLogger.cs index 2c9fbab5846..7e9f00cf37e 100644 --- a/src/Tgstation.Server.Client/IRequestLogger.cs +++ b/src/Tgstation.Server.Client/IRequestLogger.cs @@ -14,15 +14,15 @@ public interface IRequestLogger /// /// The representing the request. /// The for the operation. - /// A representing the running operation. - Task LogRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask LogRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken); /// /// Log a response. /// /// The representing the request. /// The for the operation. - /// A representing the running operation. - Task LogResponse(HttpResponseMessage responseMessage, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask LogResponse(HttpResponseMessage responseMessage, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/IServerClient.cs b/src/Tgstation.Server.Client/IServerClient.cs index 6738ca5eb49..f5dc8213653 100644 --- a/src/Tgstation.Server.Client/IServerClient.cs +++ b/src/Tgstation.Server.Client/IServerClient.cs @@ -51,7 +51,7 @@ public interface IServerClient : IDisposable /// /// The for the operation. /// A resulting in the of the target server. - Task ServerInformation(CancellationToken cancellationToken); + ValueTask ServerInformation(CancellationToken cancellationToken); /// /// Adds a to the request pipeline. diff --git a/src/Tgstation.Server.Client/IServerClientFactory.cs b/src/Tgstation.Server.Client/IServerClientFactory.cs index 69784ec7657..8cba768866b 100644 --- a/src/Tgstation.Server.Client/IServerClientFactory.cs +++ b/src/Tgstation.Server.Client/IServerClientFactory.cs @@ -20,8 +20,8 @@ public interface IServerClientFactory /// Optional s. /// Optional representing timeout for the HTTP request. /// Optional for the operation. - /// A resulting in the . - Task GetServerInformation( + /// A resulting in the . + ValueTask GetServerInformation( Uri host, IEnumerable? requestLoggers = null, TimeSpan? timeout = null, @@ -37,8 +37,8 @@ Task GetServerInformation( /// Optional representing timeout for the connection. /// Attempt to refresh the received when it expires or becomes invalid. and will be stored in memory if this is . /// Optional for the operation. - /// A resulting in a new . - Task CreateFromLogin( + /// A resulting in a new . + ValueTask CreateFromLogin( Uri host, string username, string password, @@ -56,8 +56,8 @@ Task CreateFromLogin( /// Optional initial s to add to the . /// Optional representing timeout for the connection. /// Optional for the operation. - /// A resulting in a new . - Task CreateFromOAuth( + /// A resulting in a new . + ValueTask CreateFromOAuth( Uri host, string oAuthCode, OAuthProvider oAuthProvider, diff --git a/src/Tgstation.Server.Client/IUserGroupsClient.cs b/src/Tgstation.Server.Client/IUserGroupsClient.cs index e9cb571b9dc..8af9b29f501 100644 --- a/src/Tgstation.Server.Client/IUserGroupsClient.cs +++ b/src/Tgstation.Server.Client/IUserGroupsClient.cs @@ -18,39 +18,39 @@ public interface IUserGroupsClient /// /// The of the user group to get. /// The for the operation. - /// A resulting in the requested . - Task GetId(EntityId group, CancellationToken cancellationToken); + /// A resulting in the requested . + ValueTask GetId(EntityId group, CancellationToken cancellationToken); /// /// List all s. /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of all s. - Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of all s. + ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Create a new . /// /// The . /// The for the operation. - /// The new . - Task Create(UserGroupCreateRequest group, CancellationToken cancellationToken); + /// A resulting in the new . + ValueTask Create(UserGroupCreateRequest group, CancellationToken cancellationToken); /// /// Update a . /// /// The . /// The for the operation. - /// The updated . - Task Update(UserGroupUpdateRequest group, CancellationToken cancellationToken); + /// A resulting in the updated . + ValueTask Update(UserGroupUpdateRequest group, CancellationToken cancellationToken); /// /// Deletes a . /// /// The of the user group to delete. /// The for the operation. - /// A representing the running operation. - Task Delete(EntityId group, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Delete(EntityId group, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/IUsersClient.cs b/src/Tgstation.Server.Client/IUsersClient.cs index 27847be60e3..54862d8e673 100644 --- a/src/Tgstation.Server.Client/IUsersClient.cs +++ b/src/Tgstation.Server.Client/IUsersClient.cs @@ -17,39 +17,39 @@ public interface IUsersClient /// Read the current user's information and general rights. /// /// The for the operation. - /// A resulting in the current . - Task Read(CancellationToken cancellationToken); + /// A resulting in the current . + ValueTask Read(CancellationToken cancellationToken); /// /// Get a specific . /// /// The of the to get. /// The for the operation. - /// A resulting in the requested . - Task GetId(EntityId user, CancellationToken cancellationToken); + /// A resulting in the requested . + ValueTask GetId(EntityId user, CancellationToken cancellationToken); /// /// List all s. /// /// The optional for the operation. /// The for the operation. - /// A resulting in a of all s. - Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); + /// A resulting in a of all s. + ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken); /// /// Create a new . /// /// The . /// The for the operation. - /// The new . - Task Create(UserCreateRequest user, CancellationToken cancellationToken); + /// A resulting in the new . + ValueTask Create(UserCreateRequest user, CancellationToken cancellationToken); /// /// Update a . /// /// The used to update the . /// The for the operation. - /// The updated . - Task Update(UserUpdateRequest user, CancellationToken cancellationToken); + /// A resulting in the updated . + ValueTask Update(UserUpdateRequest user, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/InstanceManagerClient.cs b/src/Tgstation.Server.Client/InstanceManagerClient.cs index 96179f01541..9da3f3f05c9 100644 --- a/src/Tgstation.Server.Client/InstanceManagerClient.cs +++ b/src/Tgstation.Server.Client/InstanceManagerClient.cs @@ -24,23 +24,23 @@ public InstanceManagerClient(IApiClient apiClient) } /// - public Task CreateOrAttach(InstanceCreateRequest instance, CancellationToken cancellationToken) => ApiClient.Create(Routes.InstanceManager, instance ?? throw new ArgumentNullException(nameof(instance)), cancellationToken); + public ValueTask CreateOrAttach(InstanceCreateRequest instance, CancellationToken cancellationToken) => ApiClient.Create(Routes.InstanceManager, instance ?? throw new ArgumentNullException(nameof(instance)), cancellationToken); /// - public Task Detach(EntityId instance, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken); + public ValueTask Detach(EntityId instance, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken); /// - public Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.InstanceManager), null, cancellationToken); /// - public Task Update(InstanceUpdateRequest instance, CancellationToken cancellationToken) => ApiClient.Update(Routes.InstanceManager, instance ?? throw new ArgumentNullException(nameof(instance)), cancellationToken); + public ValueTask Update(InstanceUpdateRequest instance, CancellationToken cancellationToken) => ApiClient.Update(Routes.InstanceManager, instance ?? throw new ArgumentNullException(nameof(instance)), cancellationToken); /// - public Task GetId(EntityId instance, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken); + public ValueTask GetId(EntityId instance, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken); /// - public Task GrantPermissions(EntityId instance, CancellationToken cancellationToken) => ApiClient.Patch(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken); + public ValueTask GrantPermissions(EntityId instance, CancellationToken cancellationToken) => ApiClient.Patch(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken); /// public IInstanceClient CreateClient(Instance instance) diff --git a/src/Tgstation.Server.Client/PaginatedClient.cs b/src/Tgstation.Server.Client/PaginatedClient.cs index 5da0b248ab0..b0f61b6a0f6 100644 --- a/src/Tgstation.Server.Client/PaginatedClient.cs +++ b/src/Tgstation.Server.Client/PaginatedClient.cs @@ -37,8 +37,8 @@ public PaginatedClient(IApiClient apiClient) /// The route. /// The optional . /// The for the operation. - /// A resulting in an of the paginated s. - protected async Task> ReadPaged( + /// A resulting in an of the paginated s. + protected async ValueTask> ReadPaged( PaginationSettings? paginationSettings, string route, long? instanceId, @@ -74,7 +74,7 @@ protected async Task> ReadPaged( } } - Task> GetPage() => instanceId.HasValue + ValueTask> GetPage() => instanceId.HasValue ? ApiClient.Read>( String.Format(CultureInfo.InvariantCulture, routeFormatter, currentPage), instanceId.Value, diff --git a/src/Tgstation.Server.Client/ServerClient.cs b/src/Tgstation.Server.Client/ServerClient.cs index f0d73b7eabd..81111d475b2 100644 --- a/src/Tgstation.Server.Client/ServerClient.cs +++ b/src/Tgstation.Server.Client/ServerClient.cs @@ -76,7 +76,7 @@ public ServerClient(IApiClient apiClient, TokenResponse token) public void Dispose() => apiClient.Dispose(); /// - public Task ServerInformation(CancellationToken cancellationToken) => apiClient.Read(Routes.Root, cancellationToken); + public ValueTask ServerInformation(CancellationToken cancellationToken) => apiClient.Read(Routes.Root, cancellationToken); /// public void AddRequestLogger(IRequestLogger requestLogger) => apiClient.AddRequestLogger(requestLogger); diff --git a/src/Tgstation.Server.Client/ServerClientFactory.cs b/src/Tgstation.Server.Client/ServerClientFactory.cs index b27e4dd9c51..fac2d79167f 100644 --- a/src/Tgstation.Server.Client/ServerClientFactory.cs +++ b/src/Tgstation.Server.Client/ServerClientFactory.cs @@ -42,7 +42,7 @@ public ServerClientFactory(ProductHeaderValue productHeaderValue) } /// - public Task CreateFromLogin( + public ValueTask CreateFromLogin( Uri host, string username, string password, @@ -69,7 +69,7 @@ public Task CreateFromLogin( } /// - public Task CreateFromOAuth( + public ValueTask CreateFromOAuth( Uri host, string oAuthCode, OAuthProvider oAuthProvider, @@ -106,7 +106,7 @@ public IServerClient CreateFromToken(Uri host, TokenResponse token) } /// - public async Task GetServerInformation( + public async ValueTask GetServerInformation( Uri host, IEnumerable? requestLoggers = null, TimeSpan? timeout = null, @@ -133,8 +133,8 @@ public async Task GetServerInformation( /// Optional representing timeout for the connection. /// If may be used to re-login in the future. /// Optional for the operation. - /// A resulting in a new . - async Task CreateWithNewToken( + /// A resulting in a new . + async ValueTask CreateWithNewToken( Uri host, ApiHeaders loginHeaders, IEnumerable? requestLoggers, diff --git a/src/Tgstation.Server.Client/UserGroupsClient.cs b/src/Tgstation.Server.Client/UserGroupsClient.cs index 449258b1198..42540b9fa66 100644 --- a/src/Tgstation.Server.Client/UserGroupsClient.cs +++ b/src/Tgstation.Server.Client/UserGroupsClient.cs @@ -23,19 +23,19 @@ public UserGroupsClient(IApiClient apiClient) } /// - public Task Create(UserGroupCreateRequest group, CancellationToken cancellationToken) => ApiClient.Create(Routes.UserGroup, group ?? throw new ArgumentNullException(nameof(group)), cancellationToken); + public ValueTask Create(UserGroupCreateRequest group, CancellationToken cancellationToken) => ApiClient.Create(Routes.UserGroup, group ?? throw new ArgumentNullException(nameof(group)), cancellationToken); /// - public Task GetId(EntityId group, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.UserGroup, group?.Id ?? throw new ArgumentNullException(nameof(group))), cancellationToken); + public ValueTask GetId(EntityId group, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.UserGroup, group?.Id ?? throw new ArgumentNullException(nameof(group))), cancellationToken); /// - public Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.UserGroup), null, cancellationToken); /// - public Task Update(UserGroupUpdateRequest group, CancellationToken cancellationToken) => ApiClient.Update(Routes.UserGroup, group ?? throw new ArgumentNullException(nameof(group)), cancellationToken); + public ValueTask Update(UserGroupUpdateRequest group, CancellationToken cancellationToken) => ApiClient.Update(Routes.UserGroup, group ?? throw new ArgumentNullException(nameof(group)), cancellationToken); /// - public Task Delete(EntityId group, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.UserGroup, group?.Id ?? throw new ArgumentNullException(nameof(group))), cancellationToken); + public ValueTask Delete(EntityId group, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.UserGroup, group?.Id ?? throw new ArgumentNullException(nameof(group))), cancellationToken); } } diff --git a/src/Tgstation.Server.Client/UsersClient.cs b/src/Tgstation.Server.Client/UsersClient.cs index 2a7b6626f73..ed60bb0acf2 100644 --- a/src/Tgstation.Server.Client/UsersClient.cs +++ b/src/Tgstation.Server.Client/UsersClient.cs @@ -23,19 +23,19 @@ public UsersClient(IApiClient apiClient) } /// - public Task Create(UserCreateRequest user, CancellationToken cancellationToken) => ApiClient.Create(Routes.User, user ?? throw new ArgumentNullException(nameof(user)), cancellationToken); + public ValueTask Create(UserCreateRequest user, CancellationToken cancellationToken) => ApiClient.Create(Routes.User, user ?? throw new ArgumentNullException(nameof(user)), cancellationToken); /// - public Task GetId(EntityId user, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.User, user?.Id ?? throw new ArgumentNullException(nameof(user))), cancellationToken); + public ValueTask GetId(EntityId user, CancellationToken cancellationToken) => ApiClient.Read(Routes.SetID(Routes.User, user?.Id ?? throw new ArgumentNullException(nameof(user))), cancellationToken); /// - public Task> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) + public ValueTask> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken) => ReadPaged(paginationSettings, Routes.ListRoute(Routes.User), null, cancellationToken); /// - public Task Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.User, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => ApiClient.Read(Routes.User, cancellationToken); /// - public Task Update(UserUpdateRequest user, CancellationToken cancellationToken) => ApiClient.Update(Routes.User, user ?? throw new ArgumentNullException(nameof(user)), cancellationToken); + public ValueTask Update(UserUpdateRequest user, CancellationToken cancellationToken) => ApiClient.Update(Routes.User, user ?? throw new ArgumentNullException(nameof(user)), cancellationToken); } } diff --git a/tests/Tgstation.Server.Client.Tests/Components/TestDreamDaemonClient.cs b/tests/Tgstation.Server.Client.Tests/Components/TestDreamDaemonClient.cs index 834a4c0054f..efd4bccc292 100644 --- a/tests/Tgstation.Server.Client.Tests/Components/TestDreamDaemonClient.cs +++ b/tests/Tgstation.Server.Client.Tests/Components/TestDreamDaemonClient.cs @@ -1,4 +1,4 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; using System.Collections.Generic; @@ -30,7 +30,8 @@ public async Task TestStart() }; var mockApiClient = new Mock(); - mockApiClient.Setup(x => x.Create(Routes.DreamDaemon, inst.Id.Value, It.IsAny())).Returns(Task.FromResult(example)); + var result2 = ValueTask.FromResult(example); + mockApiClient.Setup(x => x.Create(Routes.DreamDaemon, inst.Id.Value, It.IsAny())).Returns(result2); var client = new DreamDaemonClient(mockApiClient.Object, inst); diff --git a/tests/Tgstation.Server.Client.Tests/TestApiClient.cs b/tests/Tgstation.Server.Client.Tests/TestApiClient.cs index 31923133972..d4c81db6c3b 100644 --- a/tests/Tgstation.Server.Client.Tests/TestApiClient.cs +++ b/tests/Tgstation.Server.Client.Tests/TestApiClient.cs @@ -68,7 +68,7 @@ public async Task TestUnrecognizedResponse() var client = new ApiClient(httpClient.Object, new Uri("http://fake.com"), new ApiHeaders(new ProductHeaderValue("fake"), "fake"), null, true); - await Assert.ThrowsExceptionAsync(() => client.Read(Routes.Byond, default)); + await Assert.ThrowsExceptionAsync(() => client.Read(Routes.Byond, default).AsTask()); } } } diff --git a/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs b/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs index 63c706799d4..0c4702194e6 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Byond/TestPosixByondInstaller.cs @@ -49,7 +49,7 @@ public async Task TestDownload() var mockFileDownloader = new Mock(); var installer = new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, mockFileDownloader.Object, mockLogger.Object); - await Assert.ThrowsExceptionAsync(async () => await installer.DownloadVersion(null, default)); + await Assert.ThrowsExceptionAsync(() => installer.DownloadVersion(null, default).AsTask()); var ourArray = Array.Empty(); mockFileDownloader @@ -78,8 +78,8 @@ public async Task TestInstallByond() var installer = new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, mockFileDownloader, mockLogger.Object); const string FakePath = "fake"; - await Assert.ThrowsExceptionAsync(async () => await installer.InstallByond(null, null, default)); - await Assert.ThrowsExceptionAsync(async () => await installer.InstallByond(new Version(123,252345), null, default)); + await Assert.ThrowsExceptionAsync(() => installer.InstallByond(null, null, default).AsTask()); + await Assert.ThrowsExceptionAsync(() => installer.InstallByond(new Version(123,252345), null, default).AsTask()); await installer.InstallByond(new Version(511, 1385), FakePath, default); diff --git a/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs b/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs index 389f2e40878..a0413a91585 100644 --- a/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/Database/TestDatabaseContextFactory.cs @@ -41,7 +41,7 @@ public async Task TestWorks() var factory = new DatabaseContextFactory(mockScopeFactory.Object); - await Assert.ThrowsExceptionAsync(async () => await factory.UseContext(null)); + await Assert.ThrowsExceptionAsync(() => factory.UseContext(null).AsTask()); await factory.UseContext(context => { diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs index 87ecc100f75..0c780e04f4c 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs @@ -94,8 +94,11 @@ public TestableSwarmNode( mockDatabaseSeeder = new Mock(); mockDatabaseSeederInitialize = new Mock().Setup(x => x.Initialize(mockDatabaseContext, It.IsAny())); mockDBContextFactory = new Mock(); - mockDBContextFactory + _ = mockDBContextFactory .Setup(x => x.UseContext(It.IsNotNull>())) + .Callback>((func) => func(mockDatabaseContext)); + mockDBContextFactory + .Setup(x => x.UseContext2(It.IsNotNull>())) .Callback>((func) => func(mockDatabaseContext)); var mockHttpClientFactory = new Mock(); diff --git a/tests/Tgstation.Server.Tests/ApiAssert.cs b/tests/Tgstation.Server.Tests/ApiAssert.cs deleted file mode 100644 index e474fe50077..00000000000 --- a/tests/Tgstation.Server.Tests/ApiAssert.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Threading.Tasks; - -using Tgstation.Server.Api.Models; -using Tgstation.Server.Client; - -namespace Tgstation.Server.Tests -{ - /// - /// Extension methods for the . - /// - static class ApiAssert - { - /// - /// Test a given is thrown when a given is called. - /// - /// The type of the expected . - /// A resulting in a . - /// The expected . - /// A representing the running operation, - public static async Task ThrowsException(Func action, ErrorCode? expectedErrorCode) - where TApiException : ApiException - { - try - { - await action(); - } - catch (TApiException ex) - { - Assert.AreEqual(expectedErrorCode, ex.ErrorCode, $"Wrong error code for expected API exception! Additional Data: {ex.AdditionalServerData}"); - return; - } - - Assert.Fail($"Expected exception {typeof(TApiException)}!"); - } - } -} diff --git a/tests/Tgstation.Server.Tests/Live/AdministrationTest.cs b/tests/Tgstation.Server.Tests/Live/AdministrationTest.cs index e3253c5c0a8..adfb009d697 100644 --- a/tests/Tgstation.Server.Tests/Live/AdministrationTest.cs +++ b/tests/Tgstation.Server.Tests/Live/AdministrationTest.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -40,12 +41,12 @@ async Task TestLogs(CancellationToken cancellationToken) Assert.IsTrue(logFile.LastModified <= downloadedTuple.Item1.LastModified); Assert.IsNull(logFile.FileTicket); - await ApiAssert.ThrowsException(() => client.GetLog(new LogFileResponse + await ApiAssert.ThrowsException>(() => client.GetLog(new LogFileResponse { Name = "very_fake_path.log" }, cancellationToken), ErrorCode.IOError); - await Assert.ThrowsExceptionAsync(() => client.GetLog(new LogFileResponse + await ApiAssert.ThrowsException>(() => client.GetLog(new LogFileResponse { Name = "../out_of_bounds.file" }, cancellationToken)); diff --git a/tests/Tgstation.Server.Tests/Live/ApiAssert.cs b/tests/Tgstation.Server.Tests/Live/ApiAssert.cs new file mode 100644 index 00000000000..1fe6742015a --- /dev/null +++ b/tests/Tgstation.Server.Tests/Live/ApiAssert.cs @@ -0,0 +1,62 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Threading.Tasks; + +using Tgstation.Server.Api.Models; +using Tgstation.Server.Client; + +namespace Tgstation.Server.Tests.Live +{ + /// + /// Extension methods for the . + /// + static class ApiAssert + { + /// + /// Test a given is thrown when a given is called. + /// + /// The type of the expected . + /// A resulting in a . + /// The expected . + /// A representing the running operation, + public static async ValueTask ThrowsException(Func action, ErrorCode? expectedErrorCode = null) + where TApiException : ApiException + { + try + { + await action(); + } + catch (TApiException ex) + { + Assert.AreEqual(expectedErrorCode, ex.ErrorCode, $"Wrong error code for expected API exception! Additional Data: {ex.AdditionalServerData}"); + return; + } + + Assert.Fail($"Expected exception {typeof(TApiException)}!"); + } + + /// + /// Test a given is thrown when a given is called. + /// + /// The type of the expected . + /// The type of the returned . + /// A resulting in a . + /// The expected . + /// A representing the running operation, + public static async ValueTask ThrowsException(Func> action, ErrorCode? expectedErrorCode = null) + where TApiException : ApiException + { + try + { + await action(); + } + catch (TApiException ex) + { + Assert.AreEqual(expectedErrorCode, ex.ErrorCode, $"Wrong error code for expected API exception! Additional Data: {ex.AdditionalServerData}"); + return; + } + + Assert.Fail($"Expected exception {typeof(TApiException)}!"); + } + } +} diff --git a/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs index 68e89c0f9fd..d8fc10ce50b 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs @@ -12,6 +12,7 @@ using Tgstation.Server.Api; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Request; +using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; using Tgstation.Server.Host.Components.Byond; @@ -66,12 +67,12 @@ async Task TestDeletes(CancellationToken cancellationToken) }, cancellationToken); await WaitForJob(deleteThisOneBecauseItWasntPartOfTheOriginalTest, 30, false, null, cancellationToken); - var nonExistentUninstallResponseTask = Assert.ThrowsExceptionAsync(() => byondClient.DeleteVersion( + var nonExistentUninstallResponseTask = ApiAssert.ThrowsException(() => byondClient.DeleteVersion( new ByondVersionDeleteRequest { Version = new(509, 1000) }, - cancellationToken)); + cancellationToken), ErrorCode.ResourceNotPresent); var uninstallResponseTask = byondClient.DeleteVersion( new ByondVersionDeleteRequest @@ -80,7 +81,7 @@ async Task TestDeletes(CancellationToken cancellationToken) }, cancellationToken); - var badBecauseActiveResponseTask = ApiAssert.ThrowsException(() => byondClient.DeleteVersion( + var badBecauseActiveResponseTask = ApiAssert.ThrowsException(() => byondClient.DeleteVersion( new ByondVersionDeleteRequest { Version = new(TestVersion.Major, TestVersion.Minor, 1) @@ -214,7 +215,7 @@ async Task TestCustomInstalls(CancellationToken cancellationToken) Version = TestVersion }, null, cancellationToken); Assert.IsNull(installResponse.InstallJob); - await ApiAssert.ThrowsException(() => byondClient.SetActiveVersion(new ByondVersionRequest + await ApiAssert.ThrowsException(() => byondClient.SetActiveVersion(new ByondVersionRequest { Version = new Version(TestVersion.Major, TestVersion.Minor, 3) }, null, cancellationToken), ErrorCode.ByondNonExistentCustomVersion); diff --git a/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs index f90c1dc116e..0de1321348d 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs @@ -7,9 +7,11 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Request; +using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; +using Tgstation.Server.Common.Extensions; namespace Tgstation.Server.Tests.Live.Instance { @@ -251,7 +253,7 @@ public async Task RunPostTest(CancellationToken cancellationToken) Assert.AreEqual(2, activeBots.Count); - await Task.WhenAll(activeBots.Select(bot => chatClient.Delete(bot, cancellationToken))); + await ValueTaskExtensions.WhenAll(activeBots.Select(bot => chatClient.Delete(bot, cancellationToken)), activeBots.Count); var nowBots = await chatClient.List(null, cancellationToken); Assert.AreEqual(0, nowBots.Count); @@ -294,7 +296,7 @@ await permsClient.Update(new InstancePermissionSetRequest async Task RunLimitTests(CancellationToken cancellationToken) { - await ApiAssert.ThrowsException(() => chatClient.Create(new ChatBotCreateRequest + await ApiAssert.ThrowsException(() => chatClient.Create(new ChatBotCreateRequest { Name = "asdf", ConnectionString = "asdf", @@ -321,18 +323,18 @@ await ApiAssert.ThrowsException(() => chatClient.Create(new C ChannelData = discordBotReq.Channels.First().ChannelData }); - await ApiAssert.ThrowsException(() => chatClient.Update(discordBotReq, cancellationToken), ErrorCode.ChatBotMaxChannels); + await ApiAssert.ThrowsException(() => chatClient.Update(discordBotReq, cancellationToken), ErrorCode.ChatBotMaxChannels); var oldChannels = discordBotReq.Channels; discordBotReq.Channels = null; discordBotReq.ChannelLimit = 0; - await ApiAssert.ThrowsException(() => chatClient.Update(discordBotReq, cancellationToken), ErrorCode.ChatBotMaxChannels); + await ApiAssert.ThrowsException(() => chatClient.Update(discordBotReq, cancellationToken), ErrorCode.ChatBotMaxChannels); discordBotReq.Channels = oldChannels; discordBotReq.ChannelLimit = null; - await ApiAssert.ThrowsException(() => chatClient.Update(discordBotReq, cancellationToken), ErrorCode.ChatBotMaxChannels); + await ApiAssert.ThrowsException(() => chatClient.Update(discordBotReq, cancellationToken), ErrorCode.ChatBotMaxChannels); - await ApiAssert.ThrowsException(() => instanceClient.Update(new InstanceUpdateRequest + await ApiAssert.ThrowsException(() => instanceClient.Update(new InstanceUpdateRequest { Id = metadata.Id, ChatBotLimit = 0 diff --git a/tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs index e4171c29d54..6d8a832aa85 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs @@ -9,8 +9,8 @@ using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.System; -using Tgstation.Server.Tests.Live; namespace Tgstation.Server.Tests.Live.Instance { @@ -32,7 +32,7 @@ public DeploymentTest(IInstanceClient instanceClient, IJobsClient jobsClient, bo this.lowPriorityDeployments = lowPriorityDeployments; } - public async Task RunPreRepoClone(CancellationToken cancellationToken) + public async ValueTask RunPreRepoClone(CancellationToken cancellationToken) { Assert.IsNull(vpTest); vpTest = TestVisibilityPermission(cancellationToken); @@ -47,7 +47,7 @@ public async Task RunPreRepoClone(CancellationToken cancellationToken) Assert.AreEqual(null, dmSettings.ProjectName); } - async Task CheckDreamDaemonPriority(Task deploymentJobWaitTask, CancellationToken cancellationToken) + async ValueTask CheckDreamDaemonPriority(Task deploymentJobWaitTask, CancellationToken cancellationToken) { // this doesn't check dm's priority, but it really should @@ -149,16 +149,17 @@ async Task CompileAfterByondInstall() await CheckDreamDaemonPriority(deploymentJobWaitTask, cancellationToken); - await Task.WhenAll( - ApiAssert.ThrowsException(() => dreamDaemonClient.Update(new DreamDaemonRequest - { - Port = TestLiveServer.DMPort - }, cancellationToken), ErrorCode.PortNotAvailable), - ApiAssert.ThrowsException(() => dreamMakerClient.Update(new DreamMakerRequest - { - ApiValidationPort = TestLiveServer.DDPort - }, cancellationToken), ErrorCode.PortNotAvailable), - deploymentJobWaitTask); + var t1 = ApiAssert.ThrowsException(() => dreamDaemonClient.Update(new DreamDaemonRequest + { + Port = TestLiveServer.DMPort + }, cancellationToken), ErrorCode.PortNotAvailable); + var t2 = ApiAssert.ThrowsException(() => dreamMakerClient.Update(new DreamMakerRequest + { + ApiValidationPort = TestLiveServer.DDPort + }, cancellationToken), ErrorCode.PortNotAvailable); + await ValueTaskExtensions.WhenAll(t1, t2); + + await deploymentJobWaitTask; const string FailProject = "tests/DMAPI/BuildFail/build_fail"; var updated = await dreamMakerClient.Update(new DreamMakerRequest @@ -203,10 +204,10 @@ async Task TestVisibilityPermission(CancellationToken cancellationToken) }, cancellationToken); Assert.IsFalse((updatedPS.DreamDaemonRights.Value & DreamDaemonRights.SetVisibility) != 0); - await ApiAssert.ThrowsException(() => dreamDaemonClient.Update(new DreamDaemonRequest + await ApiAssert.ThrowsException(() => dreamDaemonClient.Update(new DreamDaemonRequest { Visibility = DreamDaemonVisibility.Private - }, cancellationToken), null); + }, cancellationToken)); updatedPS = await instanceClient.PermissionSets.Update(new InstancePermissionSetRequest { diff --git a/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs index 05f3b90ec2b..251a04dc2e9 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs @@ -40,7 +40,7 @@ public async Task> RunLongClone(CancellationToken cancellation async Task Rest() { - await ApiAssert.ThrowsException(() => repositoryClient.Read(cancellationToken), ErrorCode.RepoCloning); + await ApiAssert.ThrowsException(() => repositoryClient.Read(cancellationToken), ErrorCode.RepoCloning); Assert.IsNotNull(clone); Assert.AreEqual(cloneRequest.Origin, clone.Origin); Assert.AreEqual(workingBranch, clone.Reference); @@ -112,7 +112,7 @@ public async Task AbortLongCloneAndCloneSomethingQuick(Task longClo Assert.AreNotEqual(default, readAfterClone.RevisionInformation.Timestamp); // Specific SHA - await ApiAssert.ThrowsException(() => Checkout(new RepositoryUpdateRequest { Reference = "master", CheckoutSha = "286bb75" }, false, false, cancellationToken), ErrorCode.RepoMismatchShaAndReference); + await ApiAssert.ThrowsException(() => Checkout(new RepositoryUpdateRequest { Reference = "master", CheckoutSha = "286bb75" }, false, false, cancellationToken), ErrorCode.RepoMismatchShaAndReference); var updated = await Checkout(new RepositoryUpdateRequest { CheckoutSha = "286bb75" }, false, false, cancellationToken); // Fake SHA @@ -141,7 +141,7 @@ await repositoryClient.Update(new RepositoryUpdateRequest await TestMergeTests(updated, prNumber, cancellationToken); } - async Task Checkout(RepositoryUpdateRequest updated, bool expectFailure, bool isRef, CancellationToken cancellationToken) + async ValueTask Checkout(RepositoryUpdateRequest updated, bool expectFailure, bool isRef, CancellationToken cancellationToken) { var newRef = isRef ? updated.Reference : updated.CheckoutSha; var checkingOut = await repositoryClient.Update(updated, cancellationToken); diff --git a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs index 6c74255cd64..ccad3e8f1d0 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs @@ -65,18 +65,18 @@ await Task.WhenAll( HeartbeatSeconds = 0, Port = TestLiveServer.DDPort, LogOutput = false, - }, cancellationToken), - ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Update(new DreamDaemonRequest + }, cancellationToken).AsTask(), + ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Update(new DreamDaemonRequest { SoftShutdown = true, SoftRestart = true - }, cancellationToken), ErrorCode.DreamDaemonDoubleSoft), - ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Update(new DreamDaemonRequest + }, cancellationToken), ErrorCode.DreamDaemonDoubleSoft).AsTask(), + ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Update(new DreamDaemonRequest { Port = 0 - }, cancellationToken), ErrorCode.ModelValidationFailure), - ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.CreateDump(cancellationToken), ErrorCode.WatchdogNotRunning), - ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Restart(cancellationToken), ErrorCode.WatchdogNotRunning)); + }, cancellationToken), ErrorCode.ModelValidationFailure).AsTask(), + ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.CreateDump(cancellationToken), ErrorCode.WatchdogNotRunning).AsTask(), + ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Restart(cancellationToken), ErrorCode.WatchdogNotRunning).AsTask()); await RunBasicTest(cancellationToken); diff --git a/tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs b/tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs index 4dcefae0bcd..5b6294395c8 100644 --- a/tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs +++ b/tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Linq; -using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Net.Mime; @@ -49,7 +48,7 @@ public async Task CreateTestInstance(CancellationToken cancell }, cancellationToken); } - Task CreateTestInstanceStub(string name, CancellationToken cancellationToken) => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest + ValueTask CreateTestInstanceStub(string name, CancellationToken cancellationToken) => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest { Name = name, Path = Path.Combine(testRootPath, Guid.NewGuid().ToString()), @@ -77,14 +76,14 @@ public async Task RunPreTest(CancellationToken cancellationToken) Assert.IsTrue(Directory.Exists(firstTest.Path)); var firstClient = instanceManagerClient.CreateClient(firstTest); - await ApiAssert.ThrowsException(() => firstClient.DreamDaemon.Start(cancellationToken), ErrorCode.InstanceOffline); + await ApiAssert.ThrowsException(() => firstClient.DreamDaemon.Start(cancellationToken), ErrorCode.InstanceOffline); //cant create instances in existent directories var testNonEmpty = Path.Combine(testRootPath, Guid.NewGuid().ToString()); Directory.CreateDirectory(testNonEmpty); var testFile = Path.Combine(testNonEmpty, "asdf"); await File.WriteAllBytesAsync(testFile, Array.Empty(), cancellationToken); - await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest + await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest { Path = testNonEmpty, Name = "NonEmptyTest" @@ -98,18 +97,18 @@ await ApiAssert.ThrowsException(() => instanceManagerClient.C Name = "NonEmptyTest" }, cancellationToken); - await Assert.ThrowsExceptionAsync(() => instanceManagerClient.CreateOrAttach(FromResponse(firstTest), cancellationToken)); + await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(FromResponse(firstTest), cancellationToken), ErrorCode.InstanceAtConflictingPath); Assert.IsTrue(Directory.Exists(firstTest.Path)); //can't create instances in installation directory - await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest + await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest { Path = "./A/Local/Path", Name = "NoInstallDirTest" }, cancellationToken), ErrorCode.InstanceAtConflictingPath); //can't create instances as children of other instances - await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest + await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest { Path = Path.Combine(firstTest.Path, "subdir"), Name = "NoOtherInstanceDirTest" @@ -117,7 +116,7 @@ await ApiAssert.ThrowsException(() => instanceManagerClient.C Assert.IsTrue(Directory.Exists(firstTest.Path)); //can't move to existent directories - await ApiAssert.ThrowsException(() => instanceManagerClient.Update(new InstanceUpdateRequest + await ApiAssert.ThrowsException(() => instanceManagerClient.Update(new InstanceUpdateRequest { Id = firstTest.Id, Path = testNonEmpty @@ -129,7 +128,7 @@ await ApiAssert.ThrowsException(() => instanceManagerClient.G }, cancellationToken), ErrorCode.ResourceNotPresent); // test can't create instance outside of whitelist - await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest + await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(new InstanceCreateRequest { Name = "TestInstanceOutsideOfWhitelist", Path = Path.Combine(testRootPath, "..", Guid.NewGuid().ToString()), @@ -164,7 +163,7 @@ await ApiAssert.ThrowsException(() => instanceManagerClien Assert.IsTrue(Directory.Exists(firstTest.Path)); //can't move online instance - await ApiAssert.ThrowsException(() => instanceManagerClient.Update(new InstanceUpdateRequest + await ApiAssert.ThrowsException(() => instanceManagerClient.Update(new InstanceUpdateRequest { Id = firstTest.Id, Path = initialPath @@ -229,7 +228,7 @@ public async Task RunPostTest(Api.Models.Instance instance, CancellationToken ca firstTest = await instanceManagerClient.GetId(firstTest, cancellationToken); Assert.IsFalse(firstTest.Accessible); - await Assert.ThrowsExceptionAsync(() => instanceClient.PermissionSets.Read(cancellationToken)); + await ApiAssert.ThrowsException(() => instanceClient.PermissionSets.Read(cancellationToken)); await instanceManagerClient.GrantPermissions(new InstanceUpdateRequest { @@ -282,7 +281,7 @@ await instanceManagerClient.GrantPermissions(new InstanceUpdateRequest //but only if the attach file exists await instanceManagerClient.Detach(firstTest, cancellationToken); File.Delete(attachPath); - await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(FromResponse(firstTest), cancellationToken), ErrorCode.InstanceAtExistingPath); + await ApiAssert.ThrowsException(() => instanceManagerClient.CreateOrAttach(FromResponse(firstTest), cancellationToken), ErrorCode.InstanceAtExistingPath); } } } diff --git a/tests/Tgstation.Server.Tests/Live/RateLimitRetryingApiClient.cs b/tests/Tgstation.Server.Tests/Live/RateLimitRetryingApiClient.cs index f8cfa691411..18e759dc094 100644 --- a/tests/Tgstation.Server.Tests/Live/RateLimitRetryingApiClient.cs +++ b/tests/Tgstation.Server.Tests/Live/RateLimitRetryingApiClient.cs @@ -18,7 +18,7 @@ public RateLimitRetryingApiClient(IHttpClient httpClient, Uri url, ApiHeaders ap { } - protected override async Task RunRequest(string route, HttpContent content, HttpMethod method, long? instanceId, bool tokenRefresh, CancellationToken cancellationToken) + protected override async ValueTask RunRequest(string route, HttpContent content, HttpMethod method, long? instanceId, bool tokenRefresh, CancellationToken cancellationToken) { var hasGitHubToken = !String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN")); while (true) diff --git a/tests/Tgstation.Server.Tests/Live/RawRequestTests.cs b/tests/Tgstation.Server.Tests/Live/RawRequestTests.cs index 02884dac07f..5ab0d6c5a5f 100644 --- a/tests/Tgstation.Server.Tests/Live/RawRequestTests.cs +++ b/tests/Tgstation.Server.Tests/Live/RawRequestTests.cs @@ -206,7 +206,7 @@ static async Task TestServerInformation(IServerClientFactory clientFactory, ISer }; var badClient = clientFactory.CreateFromToken(serverClient.Url, newToken); - await Assert.ThrowsExceptionAsync(() => badClient.Administration.Read(cancellationToken)); + await ApiAssert.ThrowsException(() => badClient.Administration.Read(cancellationToken)); } static async Task TestOAuthFails(IServerClient serverClient, CancellationToken cancellationToken) diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index 01f382b0839..8f8dea63992 100644 --- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -31,6 +31,7 @@ using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Database; @@ -176,7 +177,7 @@ public async Task TestUpdateProtocolAndDisabledOAuth() var serverTask = server.Run(cancellationToken); try { - async Task TestWithoutAndWithPermission(Func> action, IServerClient client, AdministrationRights right) + async ValueTask TestWithoutAndWithPermission(Func> action, IServerClient client, AdministrationRights right) { var ourUser = await client.Users.Read(cancellationToken); var update = new UserUpdateRequest @@ -188,7 +189,7 @@ async Task TestWithoutAndWithPermission(Func(action, null); + await ApiAssert.ThrowsException(action); update.PermissionSet.AdministrationRights |= right; await client.Users.Update(update, cancellationToken); @@ -234,7 +235,7 @@ async Task TestWithoutAndWithPermission(Func( + await ApiAssert.ThrowsException( () => adminClient.Administration.Update( new ServerUpdateRequest { @@ -557,7 +558,7 @@ await Task.WhenAny( "asdfasdfasdfasdf"); using var node1BadClient = clientFactory.CreateFromToken(node1.Url, controllerUserClient.Token); - await Assert.ThrowsExceptionAsync(() => node1BadClient.Administration.Read(cancellationToken)); + await ApiAssert.ThrowsException(() => node1BadClient.Administration.Read(cancellationToken)); // check instance info is not shared var controllerInstance = await controllerClient.Instances.CreateOrAttach( @@ -584,8 +585,8 @@ await Task.WhenAny( Assert.AreEqual(controllerInstance.Id, controllerInstanceList[0].Id); Assert.IsNotNull(await controllerClient.Instances.GetId(controllerInstance, cancellationToken)); - await Assert.ThrowsExceptionAsync(() => controllerClient.Instances.GetId(node2Instance, cancellationToken)); - await Assert.ThrowsExceptionAsync(() => node1Client.Instances.GetId(controllerInstance, cancellationToken)); + await ApiAssert.ThrowsException(() => controllerClient.Instances.GetId(node2Instance, cancellationToken), ErrorCode.ResourceNotPresent); + await ApiAssert.ThrowsException(() => node1Client.Instances.GetId(controllerInstance, cancellationToken), ErrorCode.ResourceNotPresent); // test update await node1Client.Administration.Update( @@ -629,7 +630,7 @@ void CheckServerUpdated(LiveTestingServer server) using var controllerClient2 = await CreateAdminClient(controller.Url, cancellationToken); using var node1Client2 = await CreateAdminClient(node1.Url, cancellationToken); - await ApiAssert.ThrowsException(() => controllerClient2.Administration.Update( + await ApiAssert.ThrowsException(() => controllerClient2.Administration.Update( new ServerUpdateRequest { NewVersion = TestUpdateVersion @@ -860,7 +861,7 @@ await Task.WhenAny( Assert.IsNull(controllerInfo.SwarmServers.SingleOrDefault(x => x.Identifier == "node2")); // update should fail - await ApiAssert.ThrowsException( + await ApiAssert.ThrowsException( () => controllerClient2.Administration.Update(new ServerUpdateRequest { NewVersion = TestUpdateVersion @@ -1118,9 +1119,7 @@ async Task FailFast(Task task) .Select(e => instanceClient.Jobs.GetId(e, cancellationToken)) .ToList(); - await Task.WhenAll(getTasks); - jobs = getTasks - .Select(x => x.Result) + jobs = (await ValueTaskExtensions.WhenAll(getTasks)) .Where(x => x.StartedAt.Value >= preStartupTime) .ToList(); } @@ -1181,9 +1180,8 @@ async Task WaitForInitialJobs(IInstanceClient instanceClient) .Select(e => instanceClient.Jobs.GetId(e, cancellationToken)) .ToList(); - await Task.WhenAll(getTasks); - jobs = getTasks - .Select(x => x.Result) + + jobs = (await ValueTaskExtensions.WhenAll(getTasks)) .Where(x => x.StartedAt.Value > preStartupTime) .ToList(); } diff --git a/tests/Tgstation.Server.Tests/Live/UsersTest.cs b/tests/Tgstation.Server.Tests/Live/UsersTest.cs index e83f7244c6a..1a20849971f 100644 --- a/tests/Tgstation.Server.Tests/Live/UsersTest.cs +++ b/tests/Tgstation.Server.Tests/Live/UsersTest.cs @@ -10,6 +10,7 @@ using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.System; namespace Tgstation.Server.Tests.Live @@ -54,11 +55,11 @@ async Task BasicTests(CancellationToken cancellationToken) Assert.IsTrue(users.Count > 0); Assert.IsFalse(users.Any(x => x.Id == systemUser.Id)); - await ApiAssert.ThrowsException(() => serverClient.Users.GetId(systemUser, cancellationToken), null); - await ApiAssert.ThrowsException(() => serverClient.Users.Update(new UserUpdateRequest + await ApiAssert.ThrowsException(() => serverClient.Users.GetId(systemUser, cancellationToken)); + await ApiAssert.ThrowsException(() => serverClient.Users.Update(new UserUpdateRequest { Id = systemUser.Id - }, cancellationToken), null); + }, cancellationToken)); var sampleOAuthConnections = new List { @@ -68,7 +69,7 @@ await ApiAssert.ThrowsException(() => serverCl Provider = OAuthProvider.Discord } }; - await ApiAssert.ThrowsException(() => serverClient.Users.Update(new UserUpdateRequest + await ApiAssert.ThrowsException(() => serverClient.Users.Update(new UserUpdateRequest { Id = user.Id, OAuthConnections = sampleOAuthConnections @@ -135,7 +136,7 @@ await ApiAssert.ThrowsException(() => serverClient.Users.U group = await serverClient.Groups.Update(new UserGroupUpdateRequest { - Id = groups.First().Id, + Id = groups[0].Id, PermissionSet = new PermissionSet { InstanceManagerRights = RightsHelper.AllRights(), @@ -152,7 +153,7 @@ await ApiAssert.ThrowsException(() => serverClient.Users.U Password = string.Empty }; - await ApiAssert.ThrowsException(() => serverClient.Users.Create((UserCreateRequest)testUserUpdate, cancellationToken), ErrorCode.UserPasswordLength); + await ApiAssert.ThrowsException(() => serverClient.Users.Create((UserCreateRequest)testUserUpdate, cancellationToken), ErrorCode.UserPasswordLength); testUserUpdate.OAuthConnections = new List { @@ -174,7 +175,7 @@ await ApiAssert.ThrowsException(() => serverClient.Users.U Id = group.Id }, }; - await ApiAssert.ThrowsException( + await ApiAssert.ThrowsException( () => serverClient.Users.Update( testUserUpdate, cancellationToken), @@ -216,15 +217,14 @@ async Task TestCreateSysUser(CancellationToken cancellationToken) if (new PlatformIdentifier().IsWindows) await serverClient.Users.Create(update, cancellationToken); else - await ApiAssert.ThrowsException(() => serverClient.Users.Create(update, cancellationToken), ErrorCode.RequiresPosixSystemIdentity); + await ApiAssert.ThrowsException(() => serverClient.Users.Create(update, cancellationToken), ErrorCode.RequiresPosixSystemIdentity); } async Task TestSpamCreation(CancellationToken cancellationToken) { - ICollection> tasks = new List>(); - // Careful with this, very easy to overload the thread pool const int RepeatCount = 100; + var tasks = new List>(RepeatCount); ThreadPool.GetMaxThreads(out var defaultMaxWorker, out var defaultMaxCompletion); ThreadPool.GetMinThreads(out var defaultMinWorker, out var defaultMinCompletion); @@ -233,17 +233,18 @@ async Task TestSpamCreation(CancellationToken cancellationToken) ThreadPool.SetMinThreads(Math.Min(RepeatCount * 4, defaultMaxWorker), Math.Min(RepeatCount * 4, defaultMaxCompletion)); for (int i = 0; i < RepeatCount; ++i) { - tasks.Add( + var task = serverClient.Users.Create( new UserCreateRequest { Name = $"SpamTestUser_{i}", Password = "asdfasdjfhauwiehruiy273894234jhndjkwh" }, - cancellationToken)); + cancellationToken); + tasks.Add(task); } - await Task.WhenAll(tasks); + await ValueTaskExtensions.WhenAll(tasks); } finally { @@ -265,12 +266,12 @@ async Task TestPagination(CancellationToken cancellationToken) Assert.AreEqual(nullSettings.Count, emptySettings.Count); Assert.IsTrue(nullSettings.All(x => emptySettings.SingleOrDefault(y => x.Id == y.Id) != null)); - await ApiAssert.ThrowsException(() => serverClient.Users.List( + await ApiAssert.ThrowsException>(() => serverClient.Users.List( new PaginationSettings { PageSize = -2143 }, cancellationToken), ErrorCode.ApiInvalidPageOrPageSize); - await ApiAssert.ThrowsException(() => serverClient.Users.List( + await ApiAssert.ThrowsException>(() => serverClient.Users.List( new PaginationSettings { PageSize = int.MaxValue From a6a01aa15551e73fee40d48d1908e57597a1c1ae Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Mon, 19 Jun 2023 15:41:22 -0400 Subject: [PATCH 07/33] ValueTask chat `Provider`s --- .../Components/Chat/ChatManager.cs | 30 +++++++----- .../Chat/Providers/DiscordProvider.cs | 46 +++++++++---------- .../Components/Chat/Providers/IProvider.cs | 24 +++++----- .../Components/Chat/Providers/IrcProvider.cs | 16 +++---- .../Components/Chat/Providers/Provider.cs | 32 ++++++------- .../Live/DummyChatProvider.cs | 22 ++++----- 6 files changed, 87 insertions(+), 83 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 95246f2e482..7b92808477d 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -10,6 +10,7 @@ using Serilog.Context; using Tgstation.Server.Api.Models.Internal; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Chat.Commands; using Tgstation.Server.Host.Components.Chat.Providers; using Tgstation.Server.Host.Components.Interop; @@ -369,7 +370,7 @@ public Action QueueDeploymentMessage( logger.LogTrace("Sending deployment message for RevisionInformation: {revisionInfoId}", revisionInformation.Id); - var callbacks = new List>(); + var callbacks = new List>(); var task = Task.WhenAll( wdChannels.Select( @@ -412,11 +413,12 @@ public Action QueueDeploymentMessage( async Task CollateTasks(string errorMessage, string dreamMakerOutput) { await task; - await Task.WhenAll( + await ValueTaskExtensions.WhenAll( callbacks.Select( x => x( errorMessage, - dreamMakerOutput))); + dreamMakerOutput)), + callbacks.Count); } return (errorMessage, dreamMakerOutput) => AddMessageTask(CollateTasks(errorMessage, dreamMakerOutput)); @@ -928,7 +930,9 @@ async Task MonitorMessages(CancellationToken cancellationToken) lock (providers) foreach (var providerKvp in providers) if (!messageTasks.ContainsKey(providerKvp.Value)) - messageTasks.Add(providerKvp.Value, providerKvp.Value.NextMessage(cancellationToken)); + messageTasks.Add( + providerKvp.Value, + providerKvp.Value.NextMessage(cancellationToken).AsTask()); if (messageTasks.Count == 0) { @@ -999,30 +1003,32 @@ async Task WrapProcessMessage() /// A representing the running operation. Task SendMessage(IEnumerable channelIds, Message replyTo, MessageContent message, CancellationToken cancellationToken) { - channelIds = channelIds.ToList(); + var channelIdsList = channelIds.ToList(); logger.LogTrace( "Chat send \"{message}\"{embed} to channels: [{channelIdsCommaSeperated}]", message.Text, message.Embed != null ? " (with embed)" : String.Empty, - String.Join(", ", channelIds)); + String.Join(", ", channelIdsList)); - if (!channelIds.Any()) + if (!channelIdsList.Any()) return Task.CompletedTask; - return Task.WhenAll( - channelIds.Select(x => + return ValueTaskExtensions.WhenAll( + channelIdsList.Select(x => { ChannelMapping channelMapping; lock (mappedChannels) if (!mappedChannels.TryGetValue(x, out channelMapping)) - return Task.CompletedTask; + return ValueTask.CompletedTask; IProvider provider; lock (providers) if (!providers.TryGetValue(channelMapping.ProviderId, out provider)) - return Task.CompletedTask; + return ValueTask.CompletedTask; return provider.SendMessage(replyTo, message, channelMapping.ProviderChannelId, cancellationToken); - })); + }), + channelIdsList.Count) + .AsTask(); } /// diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index 81b652cf49f..e1d5d486e00 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -25,6 +25,7 @@ using Remora.Results; using Tgstation.Server.Api.Models; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Interop; using Tgstation.Server.Host.Extensions; using Tgstation.Server.Host.Jobs; @@ -285,7 +286,7 @@ public override async ValueTask DisposeAsync() } /// - public override async Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken) + public override async ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(message); @@ -376,7 +377,7 @@ await Task.WhenAll( } /// - public override async Task> SendUpdateMessage( + public override async ValueTask> SendUpdateMessage( Models.RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, @@ -628,7 +629,7 @@ public Task RespondAsync(IReady readyEvent, CancellationToken cancellati } /// - protected override async Task Connect(CancellationToken cancellationToken) + protected override async ValueTask Connect(CancellationToken cancellationToken) { try { @@ -688,7 +689,7 @@ protected override async Task Connect(CancellationToken cancellationToken) } /// - protected override async Task DisconnectImpl(CancellationToken cancellationToken) + protected override async ValueTask DisconnectImpl(CancellationToken cancellationToken) { Task localGatewayTask; CancellationTokenSource localGatewayCts; @@ -713,14 +714,14 @@ protected override async Task DisconnectImpl(CancellationToken cancellationToken } /// - protected override async Task>> MapChannelsImpl(IEnumerable channels, CancellationToken cancellationToken) + protected override async ValueTask>> MapChannelsImpl(IEnumerable channels, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(channels); var remapRequired = false; var guildsClient = serviceProvider.GetRequiredService(); - async Task>> GetModelChannelFromDBChannel(Models.ChatChannel channelFromDB) + async ValueTask>> GetModelChannelFromDBChannel(Models.ChatChannel channelFromDB) { if (!channelFromDB.DiscordChannelId.HasValue) throw new InvalidOperationException("ChatChannel missing DiscordChannelId!"); @@ -785,10 +786,13 @@ protected override async Task DisconnectImpl(CancellationToken cancellationToken var tasks = channels .Where(x => x.DiscordChannelId != 0) - .Select(GetModelChannelFromDBChannel) - .ToList(); + .Select(GetModelChannelFromDBChannel); + + var channelTuples = await ValueTaskExtensions.WhenAll(tasks.ToList()); - await Task.WhenAll(tasks); + var enumerator = channelTuples + .Where(x => x != null) + .ToList(); var channelIdZeroModel = channels.FirstOrDefault(x => x.DiscordChannelId == 0); if (channelIdZeroModel != null) @@ -798,7 +802,7 @@ protected override async Task DisconnectImpl(CancellationToken cancellationToken var unmappedTextChannels = allAccessibleChannels .Where(x => !tasks.Any(task => task.Result != null && new Snowflake(task.Result.Item1.DiscordChannelId.Value) == x.ID)); - async Task>> CreateMappingsForUnmappedChannels() + async ValueTask>> CreateMappingsForUnmappedChannels() { var unmappedTasks = unmappedTextChannels.Select( @@ -835,15 +839,10 @@ protected override async Task DisconnectImpl(CancellationToken cancellationToken } var task = CreateMappingsForUnmappedChannels(); - await task; - tasks.Add(task); + var tuple = await task; + enumerator.Add(tuple); } - var enumerator = tasks - .Select(x => x.Result) - .Where(x => x != null) - .ToList(); - lock (mappedChannels) { mappedChannels.Clear(); @@ -864,7 +863,7 @@ protected override async Task DisconnectImpl(CancellationToken cancellationToken /// /// The for the operation. /// A resulting in an of accessible and compatible s. - async Task> GetAllAccessibleTextChannels(CancellationToken cancellationToken) + async ValueTask> GetAllAccessibleTextChannels(CancellationToken cancellationToken) { var usersClient = serviceProvider.GetRequiredService(); var currentGuildsResponse = await usersClient.GetCurrentUserGuildsAsync(ct: cancellationToken); @@ -878,7 +877,7 @@ async Task> GetAllAccessibleTextChannels(CancellationToken var guildsClient = serviceProvider.GetRequiredService(); - async Task> GetGuildChannels(IPartialGuild guild) + async ValueTask> GetGuildChannels(IPartialGuild guild) { var channelsTask = guildsClient.GetGuildChannelsAsync(guild.ID.Value, cancellationToken); var threads = await guildsClient.ListActiveGuildThreadsAsync(guild.ID.Value, cancellationToken); @@ -907,13 +906,12 @@ async Task> GetGuildChannels(IPartialGuild guild) } var guildsChannelsTasks = currentGuildsResponse.Entity - .Select(GetGuildChannels) - .ToList(); + .Select(GetGuildChannels); - await Task.WhenAll(guildsChannelsTasks); + var guildsChannels = await ValueTaskExtensions.WhenAll(guildsChannelsTasks, currentGuildsResponse.Entity.Count); - var allAccessibleChannels = guildsChannelsTasks - .SelectMany(task => task.Result) + var allAccessibleChannels = guildsChannels + .SelectMany(channels => channels) .Where(guildChannel => SupportedGuildChannelTypes.Contains(guildChannel.Type)); return allAccessibleChannels; diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs index abf1eefe203..cb44d754b6a 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IProvider.cs @@ -39,27 +39,27 @@ interface IProvider : IAsyncDisposable void InitialMappingComplete(); /// - /// Get a resulting in the next the recieves or on a disconnect. + /// Get a resulting in the next the recieves or on a disconnect. /// /// The for the operation. - /// A resulting in the next available or if the needed to reconnect. - /// Note that private messages will come in the form of s not returned in . Do not the on continuations run from the returned . - Task NextMessage(CancellationToken cancellationToken); + /// A resulting in the next available or if the needed to reconnect. + /// Note that private messages will come in the form of s not returned in . + ValueTask NextMessage(CancellationToken cancellationToken); /// /// Gracefully disconnects the provider. Permanently stops the reconnection timer. /// /// The for the operation. - /// A representing the running operation. - Task Disconnect(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Disconnect(CancellationToken cancellationToken); /// /// Get the s for given . /// /// The s to map. /// The for the operation. - /// A resulting in a of the 's s representing . - Task>> MapChannels(IEnumerable channels, CancellationToken cancellationToken); + /// A resulting in a of the 's s representing . + ValueTask>> MapChannels(IEnumerable channels, CancellationToken cancellationToken); /// /// Send a message to the . @@ -68,8 +68,8 @@ interface IProvider : IAsyncDisposable /// The . /// The to send to. /// The for the operation. - /// A representing the running operation. - Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken); /// /// Set the interval at which the provider starts jobs to try to reconnect. @@ -90,8 +90,8 @@ interface IProvider : IAsyncDisposable /// The to send to. /// if the local deployment commit was pushed to the remote repository. /// The for the operation. - /// A resulting in a to call to update the message at the deployment's conclusion. Parameters: Error message if any, DreamMaker output if any. - Task> SendUpdateMessage( + /// A resulting in a to call to update the message at the deployment's conclusion. Parameters: Error message if any, DreamMaker output if any. + ValueTask> SendUpdateMessage( RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs index 3312e4b8b46..481f0fbb8d6 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs @@ -88,7 +88,7 @@ sealed class IrcProvider : Provider ulong channelIdCounter; /// - /// The used for . + /// The used for . /// Task listenTask; @@ -164,11 +164,11 @@ public override async ValueTask DisposeAsync() } /// - public override Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken) + public override async ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(message); - return Task.Factory.StartNew( + await Task.Factory.StartNew( () => { // IRC doesn't allow newlines @@ -218,7 +218,7 @@ public override Task SendMessage(Message replyTo, MessageContent message, ulong } /// - public override async Task> SendUpdateMessage( + public override async ValueTask> SendUpdateMessage( Models.RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, @@ -292,10 +292,10 @@ await SendMessage( } /// - protected override Task>> MapChannelsImpl( + protected override async ValueTask>> MapChannelsImpl( IEnumerable channels, CancellationToken cancellationToken) - => Task.Factory.StartNew( + => await Task.Factory.StartNew( () => { if (channels.Any(x => x.IrcChannel == null)) @@ -366,7 +366,7 @@ await SendMessage( TaskScheduler.Current); /// - protected override async Task Connect(CancellationToken cancellationToken) + protected override async ValueTask Connect(CancellationToken cancellationToken) { disconnecting = false; cancellationToken.ThrowIfCancellationRequested(); @@ -455,7 +455,7 @@ await Task.Factory.StartNew( } /// - protected override async Task DisconnectImpl(CancellationToken cancellationToken) + protected override async ValueTask DisconnectImpl(CancellationToken cancellationToken) { try { diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs index 1fad4023540..20bae62d134 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs @@ -85,7 +85,7 @@ protected Provider(IJobManager jobManager, IAsyncDelayer asyncDelayer, ILogger

(); - nextMessage = new TaskCompletionSource(); + nextMessage = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); initialConnectionTcs = new TaskCompletionSource(); reconnectTaskLock = new object(); @@ -113,7 +113,7 @@ public virtual async ValueTask DisposeAsync() } /// - public async Task Disconnect(CancellationToken cancellationToken) + public async ValueTask Disconnect(CancellationToken cancellationToken) { await StopReconnectionTimer(); @@ -129,7 +129,7 @@ public async Task Disconnect(CancellationToken cancellationToken) public void InitialMappingComplete() => initialConnectionTcs.TrySetResult(); /// - public async Task>> MapChannels(IEnumerable channels, CancellationToken cancellationToken) + public async ValueTask>> MapChannels(IEnumerable channels, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(channels); @@ -145,7 +145,7 @@ public async Task>> M } /// - public async Task NextMessage(CancellationToken cancellationToken) + public async ValueTask NextMessage(CancellationToken cancellationToken) { while (true) { @@ -172,17 +172,17 @@ public Task SetReconnectInterval(uint reconnectInterval, bool connectNow) { stopOldTimerTask = StopReconnectionTimer(); reconnectCts = new CancellationTokenSource(); - reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token); + reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token).AsTask(); } return stopOldTimerTask; } /// - public abstract Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken); + public abstract ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken); /// - public abstract Task> SendUpdateMessage( + public abstract ValueTask> SendUpdateMessage( RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, @@ -196,23 +196,23 @@ public abstract Task> SendUpdateMessage( /// Attempt to connect the . ///

/// The for the operation. - /// A representing the running operation. - protected abstract Task Connect(CancellationToken cancellationToken); + /// A representing the running operation. + protected abstract ValueTask Connect(CancellationToken cancellationToken); /// /// Gracefully disconnects the provider. /// /// The for the operation. - /// A representing the running operation. - protected abstract Task DisconnectImpl(CancellationToken cancellationToken); + /// A representing the running operation. + protected abstract ValueTask DisconnectImpl(CancellationToken cancellationToken); /// /// Implementation of . /// /// The s to map. /// The for the operation. - /// A resulting in a of the 's s representing . - protected abstract Task>> MapChannelsImpl( + /// A resulting in a of the 's s representing . + protected abstract ValueTask>> MapChannelsImpl( IEnumerable channels, CancellationToken cancellationToken); @@ -245,7 +245,7 @@ Task StopReconnectionTimer() reconnectCts.Cancel(); reconnectCts.Dispose(); reconnectCts = null; - Task reconnectTask = this.reconnectTask; + var reconnectTask = this.reconnectTask; this.reconnectTask = null; return reconnectTask; } @@ -261,8 +261,8 @@ Task StopReconnectionTimer() /// The amount of minutes to wait between reconnection attempts. /// If a connection attempt should be immediately made. /// The for the operation. - /// A representing the running operation. - async Task ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken) { do { diff --git a/tests/Tgstation.Server.Tests/Live/DummyChatProvider.cs b/tests/Tgstation.Server.Tests/Live/DummyChatProvider.cs index ac17312614a..290c5b46bb4 100644 --- a/tests/Tgstation.Server.Tests/Live/DummyChatProvider.cs +++ b/tests/Tgstation.Server.Tests/Live/DummyChatProvider.cs @@ -84,7 +84,7 @@ public override async ValueTask DisposeAsync() await base.DisposeAsync(); } - public override Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken) + public override ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(message); @@ -96,10 +96,10 @@ public override Task SendMessage(Message replyTo, MessageContent message, ulong if (random.Next(0, 100) > 70) throw new Exception("Random SendMessage failure!"); */ - return Task.CompletedTask; + return ValueTask.CompletedTask; } - public override Task> SendUpdateMessage(RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, string gitHubOwner, string gitHubRepo, ulong channelId, bool localCommitPushed, CancellationToken cancellationToken) + public override ValueTask> SendUpdateMessage(RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, string gitHubOwner, string gitHubRepo, ulong channelId, bool localCommitPushed, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(revisionInformation); ArgumentNullException.ThrowIfNull(byondVersion); @@ -114,7 +114,7 @@ public override Task> SendUpdateMessage(RevisionInfor if (random.Next(0, 100) > 70) throw new Exception("Random SendUpdateMessage failure!"); */ - return Task.FromResult>((_, _) => + return ValueTask.FromResult>((_, _) => { cancellationToken.ThrowIfCancellationRequested(); @@ -122,11 +122,11 @@ public override Task> SendUpdateMessage(RevisionInfor if (random.Next(0, 100) > 70) throw new Exception("Random SendUpdateMessage failure!"); */ - return Task.CompletedTask; + return ValueTask.CompletedTask; }); } - protected override Task Connect(CancellationToken cancellationToken) + protected override ValueTask Connect(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -136,20 +136,20 @@ protected override Task Connect(CancellationToken cancellationToken) connected = true; connectedOnce = true; - return Task.CompletedTask; + return ValueTask.CompletedTask; } - protected override Task DisconnectImpl(CancellationToken cancellationToken) + protected override ValueTask DisconnectImpl(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); connected = false; if (random.Next(0, 100) > 70) throw new Exception("Random disconnection failure!"); - return Task.CompletedTask; + return ValueTask.CompletedTask; } - protected override Task>> MapChannelsImpl(IEnumerable channels, CancellationToken cancellationToken) + protected override ValueTask>> MapChannelsImpl(IEnumerable channels, CancellationToken cancellationToken) { channels = channels.ToList(); @@ -159,7 +159,7 @@ protected override Task 70) throw new Exception("Random MapChannelsImpl failure!"); */ - return Task.FromResult( + return ValueTask.FromResult( new Dictionary>( channels.Select( channel => new KeyValuePair>( From 40b61a2d798288a9cceaa520bb9af74ea07caefb Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Mon, 26 Jun 2023 18:53:50 -0400 Subject: [PATCH 08/33] ValueTask ICommand --- .../Components/Chat/Commands/ByondCommand.cs | 8 ++++---- .../Components/Chat/Commands/CustomCommand.cs | 2 +- .../Components/Chat/Commands/ICommand.cs | 4 ++-- .../Components/Chat/Commands/KekCommand.cs | 2 +- .../Components/Chat/Commands/PullRequestsCommand.cs | 2 +- .../Components/Chat/Commands/RevisionCommand.cs | 2 +- .../Components/Chat/Commands/VersionCommand.cs | 2 +- .../Components/Chat/ICustomCommandHandler.cs | 4 ++-- .../Components/Watchdog/WatchdogBase.cs | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/ByondCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/ByondCommand.cs index e24c20a699b..f0c87ef4df3 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/ByondCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/ByondCommand.cs @@ -47,19 +47,19 @@ public ByondCommand(IByondManager byondManager, IWatchdog watchdog) } /// - public Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) + public ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) { if (arguments.Split(' ').Any(x => x.ToUpperInvariant() == "--ACTIVE")) - return Task.FromResult(new MessageContent + return ValueTask.FromResult(new MessageContent { Text = byondManager.ActiveVersion == null ? "None!" : String.Format(CultureInfo.InvariantCulture, "{0}.{1}", byondManager.ActiveVersion.Major, byondManager.ActiveVersion.Minor), }); if (watchdog.Status == WatchdogStatus.Offline) - return Task.FromResult(new MessageContent + return ValueTask.FromResult(new MessageContent { Text = "Server offline!", }); - return Task.FromResult(new MessageContent + return ValueTask.FromResult(new MessageContent { Text = watchdog.ActiveCompileJob?.ByondVersion ?? "None!", }); diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/CustomCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/CustomCommand.cs index 5b3c368d67b..617b1dba48b 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/CustomCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/CustomCommand.cs @@ -37,7 +37,7 @@ public void SetHandler(ICustomCommandHandler handler) } /// - public Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) + public ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) { if (handler == null) throw new InvalidOperationException("SetHandler() has not been called!"); diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/ICommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/ICommand.cs index d66df874760..766f29b6c00 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/ICommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/ICommand.cs @@ -31,7 +31,7 @@ public interface ICommand /// The text after with leading whitespace trimmed. /// The who invoked the command. /// The for the operation. - /// A resulting in a to send to the invoker. - Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken); + /// A resulting in a to send to the invoker. + ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/KekCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/KekCommand.cs index cde083b38c1..a41278ae0aa 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/KekCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/KekCommand.cs @@ -25,7 +25,7 @@ sealed class KekCommand : ICommand public bool AdminOnly => false; /// - public Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) => Task.FromResult(new MessageContent + public ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) => ValueTask.FromResult(new MessageContent { Text = Kek, }); diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs index 409c989a644..39a99bcac4e 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs @@ -79,7 +79,7 @@ public PullRequestsCommand( /// // TODO: Decomplexify #pragma warning disable CA1506 - public async Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) + public async ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) { IEnumerable results = null; var splits = arguments.Split(' '); diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs index c0028964e2a..aceff96435e 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs @@ -47,7 +47,7 @@ public RevisionCommand(IWatchdog watchdog, IRepositoryManager repositoryManager) } /// - public async Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) + public async ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) { string result; if (arguments.Split(' ').Any(x => x.ToUpperInvariant() == "--REPO")) diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/VersionCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/VersionCommand.cs index 08a7853c770..60e7f9e9a17 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/VersionCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/VersionCommand.cs @@ -36,7 +36,7 @@ public VersionCommand(IAssemblyInformationProvider assemblyInformationProvider) } /// - public Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) => Task.FromResult(new MessageContent + public ValueTask Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) => ValueTask.FromResult(new MessageContent { Text = assemblyInformationProvider.VersionString, }); diff --git a/src/Tgstation.Server.Host/Components/Chat/ICustomCommandHandler.cs b/src/Tgstation.Server.Host/Components/Chat/ICustomCommandHandler.cs index e61a890cd87..bf406bb4219 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ICustomCommandHandler.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ICustomCommandHandler.cs @@ -17,7 +17,7 @@ public interface ICustomCommandHandler /// Everything typed after minus leading spaces. /// The sending . /// The for the operation. - /// A resulting in the text to send back. - Task HandleChatCommand(string commandName, string arguments, ChatUser sender, CancellationToken cancellationToken); + /// A resulting in the text to send back. + ValueTask HandleChatCommand(string commandName, string arguments, ChatUser sender, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index 6df80546ca2..a5eed5deafe 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -267,7 +267,7 @@ public async Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, C } /// - public async Task HandleChatCommand(string commandName, string arguments, ChatUser sender, CancellationToken cancellationToken) + public async ValueTask HandleChatCommand(string commandName, string arguments, ChatUser sender, CancellationToken cancellationToken) { using (await SemaphoreSlimContext.Lock(synchronizationSemaphore, cancellationToken)) { From 4a6b549a790dbf3e8499ae9df89ffe5db74eea7f Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Mon, 26 Jun 2023 18:58:56 -0400 Subject: [PATCH 09/33] ValueTask IRestartHandler Also fix a race condition with restarting --- .../Components/Chat/ChatManager.cs | 9 ++++----- .../Components/Watchdog/WatchdogBase.cs | 2 +- src/Tgstation.Server.Host/Core/IRestartHandler.cs | 4 ++-- src/Tgstation.Server.Host/Server.cs | 12 ++++++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 7b92808477d..6690344fde5 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -536,7 +536,7 @@ public async Task DeleteConnection(long connectionId, CancellationToken cancella } /// - public Task HandleRestart(Version updateVersion, bool gracefulShutdown, CancellationToken cancellationToken) + public ValueTask HandleRestart(Version updateVersion, bool gracefulShutdown, CancellationToken cancellationToken) { var message = updateVersion == null @@ -1001,7 +1001,7 @@ async Task WrapProcessMessage() /// The to send. /// The for the operation. /// A representing the running operation. - Task SendMessage(IEnumerable channelIds, Message replyTo, MessageContent message, CancellationToken cancellationToken) + ValueTask SendMessage(IEnumerable channelIds, Message replyTo, MessageContent message, CancellationToken cancellationToken) { var channelIdsList = channelIds.ToList(); @@ -1012,7 +1012,7 @@ Task SendMessage(IEnumerable channelIds, Message replyTo, MessageContent String.Join(", ", channelIdsList)); if (!channelIdsList.Any()) - return Task.CompletedTask; + return ValueTask.CompletedTask; return ValueTaskExtensions.WhenAll( channelIdsList.Select(x => @@ -1027,8 +1027,7 @@ Task SendMessage(IEnumerable channelIds, Message replyTo, MessageContent return ValueTask.CompletedTask; return provider.SendMessage(replyTo, message, channelMapping.ProviderChannelId, cancellationToken); }), - channelIdsList.Count) - .AsTask(); + channelIdsList.Count); } /// diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index a5eed5deafe..81a7c45d7ae 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -402,7 +402,7 @@ public async Task Terminate(bool graceful, CancellationToken cancellationToken) } /// - public async Task HandleRestart(Version updateVersion, bool gracefulShutdown, CancellationToken cancellationToken) + public async ValueTask HandleRestart(Version updateVersion, bool gracefulShutdown, CancellationToken cancellationToken) { if (gracefulShutdown) { diff --git a/src/Tgstation.Server.Host/Core/IRestartHandler.cs b/src/Tgstation.Server.Host/Core/IRestartHandler.cs index 06549ff14fe..db7d3e9e8ca 100644 --- a/src/Tgstation.Server.Host/Core/IRestartHandler.cs +++ b/src/Tgstation.Server.Host/Core/IRestartHandler.cs @@ -15,7 +15,7 @@ public interface IRestartHandler /// The being updated to, if not being changed. /// If the server should not expect to restart. /// The for the operation. - /// A representing the running operation. - Task HandleRestart(Version updateVersion, bool gracefulShutdown, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask HandleRestart(Version updateVersion, bool gracefulShutdown, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Server.cs b/src/Tgstation.Server.Host/Server.cs index 6a26ed84406..2cbc26d2ec6 100644 --- a/src/Tgstation.Server.Host/Server.cs +++ b/src/Tgstation.Server.Host/Server.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Core; @@ -313,10 +314,13 @@ async Task Restart(Version newVersion, Exception exception, bool requireWatchdog var cancellationToken = cts.Token; try { - var eventsTask = Task.WhenAll( - restartHandlers.Select( - x => x.HandleRestart(newVersion, isGracefulShutdown, cancellationToken)) - .ToList()); + ValueTask eventsTask; + lock (restartLock) + eventsTask = ValueTaskExtensions.WhenAll( + restartHandlers + .Select( + x => x.HandleRestart(newVersion, isGracefulShutdown, cancellationToken)) + .ToList()); logger.LogTrace("Joining restart handlers..."); await eventsTask; From 1db1acccb0073e1045425d1ca41a87691d0f3c22 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Mon, 26 Jun 2023 19:39:42 -0400 Subject: [PATCH 10/33] .WithToken extension for ValueTasks --- .../Extensions/TaskExtensions.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs b/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs index aead718e68c..2713ea0c1c0 100644 --- a/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs @@ -56,5 +56,38 @@ public static async Task WithToken(this Task task, CancellationToken ca return await task; } + + /// + /// Create a that can be awaited while respecting a given . + /// + /// The to add cancel support to. + /// The for the operation. + /// A representing the running operation. + public static async ValueTask WithToken(this ValueTask task, CancellationToken cancellationToken) + { + var cancelTcs = new TaskCompletionSource(); + using (cancellationToken.Register(() => cancelTcs.SetCanceled())) + await Task.WhenAny(task.AsTask(), cancelTcs.Task); + + cancellationToken.ThrowIfCancellationRequested(); + await task; + } + + /// + /// Create a that can be awaited while respecting a given . + /// + /// The result of the . + /// The to add cancel support to. + /// The for the operation. + /// A resulting in the result of . + public static async ValueTask WithToken(this ValueTask task, CancellationToken cancellationToken) + { + var cancelTcs = new TaskCompletionSource(); + using (cancellationToken.Register(() => cancelTcs.SetCanceled())) + await Task.WhenAny(task.AsTask(), cancelTcs.Task); + + cancellationToken.ThrowIfCancellationRequested(); + return await task; + } } } From 6695cbd168d396716fee5240002897bb5265b4d4 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Tue, 27 Jun 2023 23:43:01 -0400 Subject: [PATCH 11/33] Fix failing tests --- src/Tgstation.Server.Client/ApiClient.cs | 4 +- .../Extensions/ValueTaskExtensions.cs | 50 +++++++------------ .../Components/Byond/ByondManager.cs | 6 +-- .../Components/Chat/ChatManager.cs | 6 +-- .../Chat/Providers/TestDiscordProvider.cs | 4 +- .../Chat/Providers/TestIrcProvider.cs | 2 +- .../Live/Instance/ChatTest.cs | 2 +- 7 files changed, 29 insertions(+), 45 deletions(-) diff --git a/src/Tgstation.Server.Client/ApiClient.cs b/src/Tgstation.Server.Client/ApiClient.cs index 02dab56be6e..ac006d19eac 100644 --- a/src/Tgstation.Server.Client/ApiClient.cs +++ b/src/Tgstation.Server.Client/ApiClient.cs @@ -317,7 +317,7 @@ protected virtual async ValueTask RunRequest( if (fileDownload) request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Octet)); - await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken)), requestLoggers.Count).ConfigureAwait(false); + await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken))).ConfigureAwait(false); response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); } @@ -330,7 +330,7 @@ protected virtual async ValueTask RunRequest( try { - await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken)), requestLoggers.Count).ConfigureAwait(false); + await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken))).ConfigureAwait(false); // just stream if (fileDownload && response.IsSuccessStatusCode) diff --git a/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs b/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs index 884b30379ae..6cb8e6ad8ac 100644 --- a/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs +++ b/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs @@ -17,14 +17,13 @@ public static class ValueTaskExtensions /// An of s. /// The number of elements in . /// A representing the combined . - /// An containing any s thrown by the . public static async ValueTask WhenAll(IEnumerable> tasks, int totalTasks) { if (tasks == null) throw new ArgumentNullException(nameof(tasks)); // We don't allocate the list if no task throws - List? exceptions = null; + Exception? exception = null; int i = 0; var results = new T[totalTasks]; foreach (var task in tasks) @@ -35,17 +34,16 @@ public static async ValueTask WhenAll(IEnumerable> tasks, i } catch (Exception ex) { - exceptions ??= new (totalTasks - i); - exceptions.Add(ex); + exception ??= ex; } ++i; } - Debug.Assert(totalTasks == i, "Invalid count specified!"); + Debug.Assert(i == totalTasks, "Incorrect totalTasks specified!"); - if (exceptions != null) - throw new AggregateException(exceptions); + if (exception != null) + throw exception; return results; } @@ -67,7 +65,7 @@ public static async ValueTask WhenAll(IReadOnlyList> tasks) return Array.Empty(); // We don't allocate the list if no task throws - List? exceptions = null; + Exception? exception = null; var results = new T[totalTasks]; for (var i = 0; i < totalTasks; i++) try @@ -76,13 +74,13 @@ public static async ValueTask WhenAll(IReadOnlyList> tasks) } catch (Exception ex) { - exceptions ??= new (totalTasks - i); - exceptions.Add(ex); + exception ??= ex; } - return exceptions == null - ? results - : throw new AggregateException(exceptions); + if (exception != null) + throw exception; + + return results; } /// @@ -91,43 +89,32 @@ public static async ValueTask WhenAll(IReadOnlyList> tasks) /// The type. /// An of s. /// A containing the of results based on . - /// An containing any s thrown by the . public static ValueTask WhenAll(params ValueTask[] tasks) => WhenAll((IReadOnlyList>)tasks); /// /// Fully a given list of . /// /// An of s. - /// The number of elements in . /// A representing the combined . - /// An containing any s thrown by the . - public static async ValueTask WhenAll(IEnumerable tasks, int totalTasks) + public static async ValueTask WhenAll(IEnumerable tasks) { if (tasks == null) throw new ArgumentNullException(nameof(tasks)); // We don't allocate the list if no task throws - List? exceptions = null; - int i = 0; + Exception? exception = null; foreach (var task in tasks) - { try { await task.ConfigureAwait(false); } catch (Exception ex) { - exceptions ??= new (totalTasks - i); - exceptions.Add(ex); + exception ??= ex; } - ++i; - } - - Debug.Assert(totalTasks == i, "Invalid count specified!"); - - if (exceptions != null) - throw new AggregateException(exceptions); + if (exception != null) + throw exception; } /// @@ -143,14 +130,15 @@ public static async ValueTask WhenAll(IReadOnlyList tasks) // We don't allocate the list if no task throws List? exceptions = null; - foreach (var task in tasks) + for (var i = 0; i < tasks.Count; ++i) try { + var task = tasks[i]; await task.ConfigureAwait(false); } catch (Exception ex) { - exceptions ??= new (); + exceptions ??= new (tasks.Count - i); exceptions.Add(ex); } diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs index 93618839fdf..ca47b957100 100644 --- a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs +++ b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs @@ -369,14 +369,12 @@ async ValueTask ReadVersion(string path) await ValueTaskExtensions.WhenAll( directories - .Select(ReadVersion), - directories.Count); + .Select(ReadVersion)); logger.LogTrace("Upgrading BYOND installations..."); await ValueTaskExtensions.WhenAll( installedVersionPaths - .Select(kvp => byondInstaller.UpgradeInstallation(kvp.Value, kvp.Key, cancellationToken)), - installedVersionPaths.Count); + .Select(kvp => byondInstaller.UpgradeInstallation(kvp.Value, kvp.Key, cancellationToken))); var activeVersionBytes = await activeVersionBytesTask; if (activeVersionBytes != null) diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 6690344fde5..674f9d2c50e 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -417,8 +417,7 @@ await ValueTaskExtensions.WhenAll( callbacks.Select( x => x( errorMessage, - dreamMakerOutput)), - callbacks.Count); + dreamMakerOutput))); } return (errorMessage, dreamMakerOutput) => AddMessageTask(CollateTasks(errorMessage, dreamMakerOutput)); @@ -1026,8 +1025,7 @@ ValueTask SendMessage(IEnumerable channelIds, Message replyTo, MessageCon if (!providers.TryGetValue(channelMapping.ProviderId, out provider)) return ValueTask.CompletedTask; return provider.SendMessage(replyTo, message, channelMapping.ProviderChannelId, cancellationToken); - }), - channelIdsList.Count); + })); } /// 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 21fabce4d74..db7ee0b40b2 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs @@ -63,7 +63,7 @@ public async Task TestConstructionAndDisposal() await new DiscordProvider(mockJobManager, mockDel, mockLogger, mockAss, bot).DisposeAsync(); } - static Task InvokeConnect(IProvider provider, CancellationToken cancellationToken = default) => (Task)provider.GetType().GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(provider, new object[] { cancellationToken }); + static ValueTask InvokeConnect(IProvider provider, CancellationToken cancellationToken = default) => (ValueTask)provider.GetType().GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(provider, new object[] { cancellationToken }); [TestMethod] public async Task TestConnectWithFakeTokenFails() @@ -74,7 +74,7 @@ public async Task TestConnectWithFakeTokenFails() ReconnectionInterval = 1, ConnectionString = "asdf" }); - await Assert.ThrowsExceptionAsync(() => InvokeConnect(provider)); + await Assert.ThrowsExceptionAsync(async () => await InvokeConnect(provider)); Assert.IsFalse(provider.Connected); } 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 87f61edf6f9..7bf25186286 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs @@ -52,7 +52,7 @@ public async Task TestConstructionAndDisposal() await new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockAss.Object, mockBot).DisposeAsync(); } - static Task InvokeConnect(IProvider provider, CancellationToken cancellationToken = default) => (Task)provider.GetType().GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(provider, new object[] { cancellationToken }); + static ValueTask InvokeConnect(IProvider provider, CancellationToken cancellationToken = default) => (ValueTask)provider.GetType().GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(provider, new object[] { cancellationToken }); [TestMethod] public async Task TestConnectAndDisconnect() diff --git a/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs index 0de1321348d..dc5251c8389 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs @@ -253,7 +253,7 @@ public async Task RunPostTest(CancellationToken cancellationToken) Assert.AreEqual(2, activeBots.Count); - await ValueTaskExtensions.WhenAll(activeBots.Select(bot => chatClient.Delete(bot, cancellationToken)), activeBots.Count); + await ValueTaskExtensions.WhenAll(activeBots.Select(bot => chatClient.Delete(bot, cancellationToken))); var nowBots = await chatClient.List(null, cancellationToken); Assert.AreEqual(0, nowBots.Count); From 4c07495ba472cea9368b5340c9c990ae0816dece Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sun, 13 Aug 2023 23:36:36 -0400 Subject: [PATCH 12/33] One less async ValueTask --- src/Tgstation.Server.Client/ApiClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tgstation.Server.Client/ApiClient.cs b/src/Tgstation.Server.Client/ApiClient.cs index 4f205a23530..a235496592b 100644 --- a/src/Tgstation.Server.Client/ApiClient.cs +++ b/src/Tgstation.Server.Client/ApiClient.cs @@ -221,9 +221,9 @@ public ValueTask Delete(string route, long instanceId, CancellationToken cancell => RunRequest(route, HttpMethod.Delete, instanceId, false, cancellationToken); /// - public async ValueTask Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) + public ValueTask Delete(string route, TBody body, long instanceId, CancellationToken cancellationToken) where TBody : class - => await RunRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken); + => RunResultlessRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken); /// public ValueTask Delete(string route, long instanceId, CancellationToken cancellationToken) From c824d72e5c8123796d9bd4b15ff8601ee378f2bb Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 29 Sep 2023 11:41:43 -0400 Subject: [PATCH 13/33] Update to Wix 4.0.2 --- build/package/winget/.config/dotnet-tools.json | 2 +- .../Tgstation.Server.Host.Service.Wix.Bundle.wixproj | 8 ++++---- .../Tgstation.Server.Host.Service.Wix.Extensions.csproj | 4 ++-- .../Tgstation.Server.Host.Service.Wix.wixproj | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/package/winget/.config/dotnet-tools.json b/build/package/winget/.config/dotnet-tools.json index 6d50916bb0b..14178b0a98b 100644 --- a/build/package/winget/.config/dotnet-tools.json +++ b/build/package/winget/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "wix": { - "version": "4.0.1", + "version": "4.0.2", "commands": [ "wix" ] diff --git a/build/package/winget/Tgstation.Server.Host.Service.Wix.Bundle/Tgstation.Server.Host.Service.Wix.Bundle.wixproj b/build/package/winget/Tgstation.Server.Host.Service.Wix.Bundle/Tgstation.Server.Host.Service.Wix.Bundle.wixproj index 1858d41c47b..5f7032e3e52 100644 --- a/build/package/winget/Tgstation.Server.Host.Service.Wix.Bundle/Tgstation.Server.Host.Service.Wix.Bundle.wixproj +++ b/build/package/winget/Tgstation.Server.Host.Service.Wix.Bundle/Tgstation.Server.Host.Service.Wix.Bundle.wixproj @@ -1,4 +1,4 @@ - + ProductVersion=$(TgsCoreVersion);NetMajorVersion=$(TgsNetMajorVersion);DotnetRedistUrl=$(TgsDotnetRedistUrl);MariaDBRedistUrl=$(TgsMariaDBRedistUrl) @@ -24,10 +24,10 @@ - - + + - \ No newline at end of file + diff --git a/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj b/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj index acadffcec18..c7edd3c403f 100644 --- a/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj +++ b/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj @@ -7,7 +7,7 @@ - + @@ -15,7 +15,7 @@ True - + diff --git a/build/package/winget/Tgstation.Server.Host.Service.Wix/Tgstation.Server.Host.Service.Wix.wixproj b/build/package/winget/Tgstation.Server.Host.Service.Wix/Tgstation.Server.Host.Service.Wix.wixproj index f03f8f41b28..14838b0531e 100644 --- a/build/package/winget/Tgstation.Server.Host.Service.Wix/Tgstation.Server.Host.Service.Wix.wixproj +++ b/build/package/winget/Tgstation.Server.Host.Service.Wix/Tgstation.Server.Host.Service.Wix.wixproj @@ -1,4 +1,4 @@ - + ProductVersion=$(TgsCoreVersion) @@ -25,8 +25,8 @@ - - + + From 2a83af6896ac33d0f6c06e567fa39f77590ae202 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 29 Sep 2023 18:04:36 -0400 Subject: [PATCH 14/33] Nuget package updates --- build/Version.props | 2 +- .../Tgstation.Server.Host.Service.csproj | 2 +- .../.config/dotnet-tools.json | 2 +- .../Tgstation.Server.Host.csproj | 22 +++++++++---------- .../Tgstation.Server.ReleaseNotes/Program.cs | 9 ++------ 5 files changed, 16 insertions(+), 21 deletions(-) diff --git a/build/Version.props b/build/Version.props index 4dd29db8a00..9e2d5231999 100644 --- a/build/Version.props +++ b/build/Version.props @@ -17,7 +17,7 @@ netstandard2.0 6 - https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.21/dotnet-hosting-6.0.21-win.exe + https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.22/dotnet-hosting-6.0.22-win.exe 10.11.5 https://ftp.osuosl.org/pub/mariadb//mariadb-10.11.5/winx64-packages/mariadb-10.11.5-winx64.msi diff --git a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj index 62ef77cf57c..40b77d40cab 100644 --- a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj +++ b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/Tgstation.Server.Host/.config/dotnet-tools.json b/src/Tgstation.Server.Host/.config/dotnet-tools.json index 236008e3ee9..c418dc80b94 100644 --- a/src/Tgstation.Server.Host/.config/dotnet-tools.json +++ b/src/Tgstation.Server.Host/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "7.0.10", + "version": "7.0.11", "commands": [ "dotnet-ef" ] diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index e979588d4ca..ea827e234e6 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -75,27 +75,27 @@ - + - + - + - + runtime; build; native; contentfiles; analyzers; buildtransitive - + - + - + - + @@ -115,13 +115,13 @@ - + - + - + diff --git a/tools/Tgstation.Server.ReleaseNotes/Program.cs b/tools/Tgstation.Server.ReleaseNotes/Program.cs index 2542c7b78cb..21bdbc1bfa8 100644 --- a/tools/Tgstation.Server.ReleaseNotes/Program.cs +++ b/tools/Tgstation.Server.ReleaseNotes/Program.cs @@ -730,11 +730,6 @@ async Task CommitNotes(Component component, List notes) return Tuple.Create(changelists.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), await componentVersions, isReleasePR); } - class ExtendedReleaseUpdate : ReleaseUpdate - { - public bool? MakeLatest { get; set; } - } - static async Task EnsureRelease(IGitHubClient client) { Console.WriteLine("Ensuring latest release is a GitHub release..."); @@ -753,9 +748,9 @@ static async Task EnsureRelease(IGitHubClient client) .First(); // this should set it as latest - await client.Repository.Release.Edit(RepoOwner, RepoName, latestRelease.Id, new ExtendedReleaseUpdate + await client.Repository.Release.Edit(RepoOwner, RepoName, latestRelease.Id, new ReleaseUpdate { - MakeLatest = true + MakeLatest = MakeLatestQualifier.True }); } From 9129638bb55e339578c9806e7b7ccd837b354241 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 14:41:29 -0400 Subject: [PATCH 15/33] More ValueTask conversions --- .../Components/Chat/ChatManager.cs | 6 ++--- .../Components/Chat/ChatTrackingContext.cs | 6 ++--- .../Components/Chat/IChannelSink.cs | 4 ++-- .../Components/Deployment/DmbFactory.cs | 6 ++--- .../Components/Deployment/DreamMaker.cs | 2 +- .../Components/Deployment/ICompileJobSink.cs | 4 ++-- .../Components/Deployment/IDmbFactory.cs | 8 +++---- .../Components/Deployment/IDreamMaker.cs | 4 ++-- .../Components/IInstanceCore.cs | 4 ++-- .../Components/IInstanceOperations.cs | 12 +++++----- .../Components/IRenameNotifyee.cs | 4 ++-- .../Components/Instance.cs | 21 ++++++++-------- .../Components/InstanceManager.cs | 6 ++--- .../Components/InstanceWrapper.cs | 4 ++-- .../Repository/IRepositoryManager.cs | 12 +++++----- .../Repository/RepositoryManager.cs | 6 ++--- .../Repository/RepositoryUpdateService.cs | 8 +++---- .../Components/Session/ISessionController.cs | 12 +++++----- .../Components/Session/SessionController.cs | 16 ++++++------- .../Components/Watchdog/BasicWatchdog.cs | 6 ++--- .../Components/Watchdog/IWatchdog.cs | 24 +++++++++---------- .../Components/Watchdog/WatchdogBase.cs | 14 +++++------ .../Controllers/ByondController.cs | 2 +- .../Jobs/JobEntrypoint.cs | 4 ++-- 24 files changed, 96 insertions(+), 99 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 5fe5e2bbe2a..0231bc973e7 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -606,7 +606,7 @@ async Task RemoveProviderChannels(long connectionId, bool removeProvi providers.Remove(connectionId); } - Task trackingContextsUpdateTask; + ValueTask trackingContextsUpdateTask; lock (mappedChannels) { foreach (var mappedConnectionChannel in mappedChannels.Where(x => x.Value.ProviderId == connectionId).Select(x => x.Key).ToList()) @@ -616,9 +616,9 @@ async Task RemoveProviderChannels(long connectionId, bool removeProvi if (removeProvider) lock (trackingContexts) - trackingContextsUpdateTask = Task.WhenAll(trackingContexts.Select(x => x.UpdateChannels(newMappedChannels, cancellationToken))); + trackingContextsUpdateTask = ValueTaskExtensions.WhenAll(trackingContexts.Select(x => x.UpdateChannels(newMappedChannels, cancellationToken))); else - trackingContextsUpdateTask = Task.CompletedTask; + trackingContextsUpdateTask = ValueTask.CompletedTask; } await trackingContextsUpdateTask; diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatTrackingContext.cs b/src/Tgstation.Server.Host/Components/Chat/ChatTrackingContext.cs index c390147b62d..369ccdeeebe 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatTrackingContext.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatTrackingContext.cs @@ -133,15 +133,15 @@ public void SetChannelSink(IChannelSink channelSink) } /// - public Task UpdateChannels(IEnumerable newChannels, CancellationToken cancellationToken) + public ValueTask UpdateChannels(IEnumerable newChannels, CancellationToken cancellationToken) { logger.LogTrace("UpdateChannels..."); var completed = newChannels.ToList(); - Task updateTask; + ValueTask updateTask; lock (synchronizationLock) { Channels = completed; - updateTask = channelSink?.UpdateChannels(newChannels, cancellationToken) ?? Task.CompletedTask; + updateTask = channelSink?.UpdateChannels(newChannels, cancellationToken) ?? ValueTask.CompletedTask; } return updateTask; diff --git a/src/Tgstation.Server.Host/Components/Chat/IChannelSink.cs b/src/Tgstation.Server.Host/Components/Chat/IChannelSink.cs index 26b6f6b96f2..e9e366902e4 100644 --- a/src/Tgstation.Server.Host/Components/Chat/IChannelSink.cs +++ b/src/Tgstation.Server.Host/Components/Chat/IChannelSink.cs @@ -14,7 +14,7 @@ public interface IChannelSink /// /// The of new s. /// The for the operation. - /// A representing the running operation. - Task UpdateChannels(IEnumerable newChannels, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask UpdateChannels(IEnumerable newChannels, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs index 09567ba79cd..2b6e2d12b33 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs @@ -128,7 +128,7 @@ public DmbFactory( public void Dispose() => cleanupCts.Dispose(); // we don't dispose nextDmbProvider here, since it might be the only thing we have /// - public async Task LoadCompileJob(CompileJob job, Action activationAction, CancellationToken cancellationToken) + public async ValueTask LoadCompileJob(CompileJob job, Action activationAction, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(job); @@ -222,7 +222,7 @@ public async Task StopAsync(CancellationToken cancellationToken) /// #pragma warning disable CA1506 // TODO: Decomplexify - public async Task FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken) + public async ValueTask FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(compileJob); @@ -327,7 +327,7 @@ void CleanupAction() /// #pragma warning disable CA1506 // TODO: Decomplexify - public async Task CleanUnusedCompileJobs(CancellationToken cancellationToken) + public async ValueTask CleanUnusedCompileJobs(CancellationToken cancellationToken) { List jobIdsToSkip; diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs index 665efba795e..7454f410d79 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs @@ -192,7 +192,7 @@ public DreamMaker( /// #pragma warning disable CA1506 - public async Task DeploymentProcess( + public async ValueTask DeploymentProcess( Models.Job job, IDatabaseContextFactory databaseContextFactory, JobProgressReporter progressReporter, diff --git a/src/Tgstation.Server.Host/Components/Deployment/ICompileJobSink.cs b/src/Tgstation.Server.Host/Components/Deployment/ICompileJobSink.cs index 086301c87fc..49d4eae165e 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/ICompileJobSink.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/ICompileJobSink.cs @@ -17,7 +17,7 @@ public interface ICompileJobSink : ILatestCompileJobProvider /// The to load. /// An to be called when the becomes active or is discarded with or respectively. /// The for the operation. - /// A representing the running operation. - Task LoadCompileJob(CompileJob job, Action activationAction, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask LoadCompileJob(CompileJob job, Action activationAction, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs index 0d10b7dcd1c..6ff04b0a00f 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs @@ -34,14 +34,14 @@ public interface IDmbFactory : ILatestCompileJobProvider, IComponentService, IDi /// /// The to make the for. /// The for the operation. - /// A resulting in a new representing the on success, on failure. - Task FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken); + /// A resulting in a new representing the on success, on failure. + ValueTask FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken); /// /// Deletes all compile jobs that are inactive in the Game folder. /// /// The for the operation. - /// A representing the running operation. - Task CleanUnusedCompileJobs(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CleanUnusedCompileJobs(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Deployment/IDreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/IDreamMaker.cs index 0f5421691dd..32443080165 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/IDreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/IDreamMaker.cs @@ -19,8 +19,8 @@ public interface IDreamMaker /// The for the operation. /// The to report compilation progress. /// The for the operation. - /// A representing the running operation. - Task DeploymentProcess( + /// A representing the running operation. + ValueTask DeploymentProcess( Job job, IDatabaseContextFactory databaseContextFactory, JobProgressReporter progressReporter, diff --git a/src/Tgstation.Server.Host/Components/IInstanceCore.cs b/src/Tgstation.Server.Host/Components/IInstanceCore.cs index 101ca82e01c..d42b4e69da0 100644 --- a/src/Tgstation.Server.Host/Components/IInstanceCore.cs +++ b/src/Tgstation.Server.Host/Components/IInstanceCore.cs @@ -48,7 +48,7 @@ public interface IInstanceCore : ILatestCompileJobProvider, IRenameNotifyee /// Change the for the . /// /// The new auto update inteval. - /// A representing the running operation. - Task SetAutoUpdateInterval(uint newInterval); + /// A representing the running operation. + ValueTask SetAutoUpdateInterval(uint newInterval); } } diff --git a/src/Tgstation.Server.Host/Components/IInstanceOperations.cs b/src/Tgstation.Server.Host/Components/IInstanceOperations.cs index 701b937d527..3212d9d6dcf 100644 --- a/src/Tgstation.Server.Host/Components/IInstanceOperations.cs +++ b/src/Tgstation.Server.Host/Components/IInstanceOperations.cs @@ -15,8 +15,8 @@ public interface IInstanceOperations /// /// The of the desired . /// The for the operation. - /// A representing the running operation. - Task OnlineInstance(Models.Instance metadata, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask OnlineInstance(Models.Instance metadata, CancellationToken cancellationToken); /// /// Offline an . @@ -24,8 +24,8 @@ public interface IInstanceOperations /// The of the desired . /// The performing the operation. /// The for the operation. - /// A representing the running operation. - Task OfflineInstance(Models.Instance metadata, User user, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask OfflineInstance(Models.Instance metadata, User user, CancellationToken cancellationToken); /// /// Move an . @@ -33,7 +33,7 @@ public interface IInstanceOperations /// The of the desired with the updated path. /// The old path of the . will have this set on if the operation fails. /// The for the operation. - /// A representing the running operation. - Task MoveInstance(Models.Instance metadata, string oldPath, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask MoveInstance(Models.Instance metadata, string oldPath, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs b/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs index 03844a75105..be22158bd9d 100644 --- a/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs +++ b/src/Tgstation.Server.Host/Components/IRenameNotifyee.cs @@ -13,7 +13,7 @@ public interface IRenameNotifyee /// /// The new . /// The for the operation. - /// A representing the running operation. - Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index c6d1e40586f..f812c51e740 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -167,7 +167,7 @@ public async ValueTask DisposeAsync() } /// - public Task InstanceRenamed(string newName, CancellationToken cancellationToken) + public ValueTask InstanceRenamed(string newName, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(newName); if (String.IsNullOrWhiteSpace(newName)) @@ -183,11 +183,11 @@ public async Task StartAsync(CancellationToken cancellationToken) using (LogContext.PushProperty(SerilogContextHelper.InstanceIdContextProperty, metadata.Id)) { await Task.WhenAll( - SetAutoUpdateInterval(metadata.AutoUpdateInterval.Value), - Configuration.StartAsync(cancellationToken), - ByondManager.StartAsync(cancellationToken), - Chat.StartAsync(cancellationToken), - dmbFactory.StartAsync(cancellationToken)); + SetAutoUpdateInterval(metadata.AutoUpdateInterval.Value).AsTask(), + Configuration.StartAsync(cancellationToken), + ByondManager.StartAsync(cancellationToken), + Chat.StartAsync(cancellationToken), + dmbFactory.StartAsync(cancellationToken)); // dependent on so many things, its just safer this way await Watchdog.StartAsync(cancellationToken); @@ -213,7 +213,7 @@ await Task.WhenAll( } /// - public async Task SetAutoUpdateInterval(uint newInterval) + public async ValueTask SetAutoUpdateInterval(uint newInterval) { Task toWait; lock (timerLock) @@ -263,9 +263,9 @@ public async Task SetAutoUpdateInterval(uint newInterval) /// The being run. /// The progress reporter action for the . /// The for the operation. - /// A representing the running operation. + /// A representing the running operation. #pragma warning disable CA1502 // Cyclomatic complexity - Task RepositoryAutoUpdateJob( + ValueTask RepositoryAutoUpdateJob( IInstanceCore core, IDatabaseContextFactory databaseContextFactory, Job job, @@ -480,8 +480,7 @@ await repo.ResetToOrigin( await repo.ResetToSha(startSha, progressReporter, CancellationToken.None); throw; } - }) - .AsTask(); + }); #pragma warning restore CA1502 // Cyclomatic complexity /// diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs index ef1a5570d29..f15847d80d9 100644 --- a/src/Tgstation.Server.Host/Components/InstanceManager.cs +++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs @@ -246,7 +246,7 @@ public IInstanceReference GetInstanceReference(Api.Models.Instance metadata) } /// - public async Task MoveInstance(Models.Instance instance, string oldPath, CancellationToken cancellationToken) + public async ValueTask MoveInstance(Models.Instance instance, string oldPath, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(oldPath); @@ -317,7 +317,7 @@ await ioManager.WriteAllBytes( } /// - public async Task OfflineInstance(Models.Instance metadata, Models.User user, CancellationToken cancellationToken) + public async ValueTask OfflineInstance(Models.Instance metadata, Models.User user, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(metadata); @@ -383,7 +383,7 @@ await databaseContextFactory.UseContext( } /// - public async Task OnlineInstance(Models.Instance metadata, CancellationToken cancellationToken) + public async ValueTask OnlineInstance(Models.Instance metadata, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(metadata); diff --git a/src/Tgstation.Server.Host/Components/InstanceWrapper.cs b/src/Tgstation.Server.Host/Components/InstanceWrapper.cs index 3ea82d62d85..c8524b50e22 100644 --- a/src/Tgstation.Server.Host/Components/InstanceWrapper.cs +++ b/src/Tgstation.Server.Host/Components/InstanceWrapper.cs @@ -48,10 +48,10 @@ public InstanceWrapper() } /// - public Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) => Instance.InstanceRenamed(newInstanceName, cancellationToken); + public ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) => Instance.InstanceRenamed(newInstanceName, cancellationToken); /// - public Task SetAutoUpdateInterval(uint newInterval) => Instance.SetAutoUpdateInterval(newInterval); + public ValueTask SetAutoUpdateInterval(uint newInterval) => Instance.SetAutoUpdateInterval(newInterval); /// public CompileJob LatestCompileJob() => Instance.LatestCompileJob(); diff --git a/src/Tgstation.Server.Host/Components/Repository/IRepositoryManager.cs b/src/Tgstation.Server.Host/Components/Repository/IRepositoryManager.cs index 03a28fe41b5..f7c4a546083 100644 --- a/src/Tgstation.Server.Host/Components/Repository/IRepositoryManager.cs +++ b/src/Tgstation.Server.Host/Components/Repository/IRepositoryManager.cs @@ -25,8 +25,8 @@ public interface IRepositoryManager : IDisposable /// Attempt to load the from the default location. /// /// The for the operation. - /// The loaded if it exists, otherwise. - Task LoadRepository(CancellationToken cancellationToken); + /// A resulting in the loaded if it exists, otherwise. + ValueTask LoadRepository(CancellationToken cancellationToken); /// /// Clone the repository at . @@ -38,8 +38,8 @@ public interface IRepositoryManager : IDisposable /// The for progress of the clone. /// If submodules should be recusively cloned and initialized. /// The for the operation. - /// The newly cloned , if one already exists. - Task CloneRepository( + /// A resulting i the newly cloned , if one already exists. + ValueTask CloneRepository( Uri url, string initialBranch, string username, @@ -52,7 +52,7 @@ Task CloneRepository( /// Delete the current repository. /// /// The for the operation. - /// A representing the running operation. - Task DeleteRepository(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask DeleteRepository(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs index ebe99aa8084..61b6e609b03 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs @@ -117,7 +117,7 @@ public void Dispose() } /// - public async Task CloneRepository( + public async ValueTask CloneRepository( Uri url, string initialBranch, string username, @@ -202,7 +202,7 @@ await repositoryFactory.Clone( } /// - public async Task LoadRepository(CancellationToken cancellationToken) + public async ValueTask LoadRepository(CancellationToken cancellationToken) { logger.LogTrace("Begin LoadRepository..."); lock (semaphore) @@ -248,7 +248,7 @@ public async Task LoadRepository(CancellationToken cancellationToke } /// - public async Task DeleteRepository(CancellationToken cancellationToken) + public async ValueTask DeleteRepository(CancellationToken cancellationToken) { logger.LogInformation("Deleting repository..."); try diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs index 5bf499d15bc..93339cc96fa 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs @@ -6,9 +6,9 @@ using LibGit2Sharp; -using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; + using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Request; using Tgstation.Server.Host.Database; @@ -142,9 +142,9 @@ public static async Task LoadRevisionInformation( /// The running , ignored. /// The for the job. /// The for the operation. - /// A representing the running operation. + /// A representing the running operation. #pragma warning disable CA1502, CA1506 // TODO: Decomplexify - public async Task RepositoryUpdateJob( + public async ValueTask RepositoryUpdateJob( IInstanceCore instance, IDatabaseContextFactory databaseContextFactory, Job job, @@ -557,8 +557,6 @@ await repo.Sychronize( cancellationToken); await UpdateRevInfo(); } - - return null; } catch { diff --git a/src/Tgstation.Server.Host/Components/Session/ISessionController.cs b/src/Tgstation.Server.Host/Components/Session/ISessionController.cs index 3ded84429ac..a42186c66b9 100644 --- a/src/Tgstation.Server.Host/Components/Session/ISessionController.cs +++ b/src/Tgstation.Server.Host/Components/Session/ISessionController.cs @@ -87,16 +87,16 @@ interface ISessionController : IProcessBase, IRenameNotifyee, IAsyncDisposable /// /// Releases the without terminating it. Also calls . /// - /// A representing the running operation. - Task Release(); + /// A representing the running operation. + ValueTask Release(); /// /// Sends a command to DreamDaemon through /world/Topic(). /// /// The to send. /// The for the operation. - /// A resulting in the of /world/Topic(). - Task SendCommand(TopicParameters parameters, CancellationToken cancellationToken); + /// A resulting in the of /world/Topic(). + ValueTask SendCommand(TopicParameters parameters, CancellationToken cancellationToken); /// /// Causes the world to start listening on a . @@ -111,8 +111,8 @@ interface ISessionController : IProcessBase, IRenameNotifyee, IAsyncDisposable /// /// The new . /// The for the operation. - /// A resulting in if the operation succeeded, otherwise. - Task SetRebootState(RebootState newRebootState, CancellationToken cancellationToken); + /// A resulting in if the operation succeeded, otherwise. + ValueTask SetRebootState(RebootState newRebootState, CancellationToken cancellationToken); /// /// Changes to without telling the DMAPI. diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs index 2da8c03b58f..f687e9b6c45 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs @@ -385,7 +385,7 @@ public async Task ProcessBridgeRequest(BridgeParameters paramete public void EnableCustomChatCommands() => chatTrackingContext.Active = DMApiAvailable; /// - public async Task Release() + public ValueTask Release() { CheckDisposed(); @@ -393,11 +393,11 @@ public async Task Release() ReattachInformation.InitialDmb?.KeepAlive(); byondLock.DoNotDeleteThisSession(); released = true; - await DisposeAsync(); + return DisposeAsync(); } /// - public async Task SendCommand(TopicParameters parameters, CancellationToken cancellationToken) + public async ValueTask SendCommand(TopicParameters parameters, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(parameters); @@ -519,7 +519,7 @@ async Task ImmediateTopicPortChange() } /// - public async Task SetRebootState(RebootState newRebootState, CancellationToken cancellationToken) + public async ValueTask SetRebootState(RebootState newRebootState, CancellationToken cancellationToken) { if (RebootState == newRebootState) return true; @@ -560,15 +560,15 @@ public IDisposable ReplaceDmbProvider(IDmbProvider dmbProvider) } /// - public Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) + public async ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) { ReattachInformation.RuntimeInformation.InstanceName = newInstanceName; - return SendCommand(new TopicParameters(newInstanceName), cancellationToken); + await SendCommand(new TopicParameters(newInstanceName), cancellationToken); } /// - public Task UpdateChannels(IEnumerable newChannels, CancellationToken cancellationToken) - => SendCommand( + public async ValueTask UpdateChannels(IEnumerable newChannels, CancellationToken cancellationToken) + => await SendCommand( new TopicParameters( new ChatUpdate(newChannels)), cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs index 62f1bbca7f9..4bbb5956e61 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs @@ -91,7 +91,7 @@ public BasicWatchdog( } /// - public override Task ResetRebootState(CancellationToken cancellationToken) + public override ValueTask ResetRebootState(CancellationToken cancellationToken) { if (!gracefulRebootRequired) return base.ResetRebootState(cancellationToken); @@ -100,8 +100,8 @@ public override Task ResetRebootState(CancellationToken cancellationToken) } /// - public sealed override Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) - => Server?.InstanceRenamed(newInstanceName, cancellationToken) ?? Task.CompletedTask; + public sealed override ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken) + => Server?.InstanceRenamed(newInstanceName, cancellationToken) ?? ValueTask.CompletedTask; /// protected override async Task HandleMonitorWakeup(MonitorActivationReason reason, CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs index 1e908eb85f9..360d3fcfc34 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs @@ -48,45 +48,45 @@ public interface IWatchdog : IComponentService, IAsyncDisposable, IEventConsumer /// Start the . /// /// The for the operation. - /// A representing the running operation. - Task Launch(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Launch(CancellationToken cancellationToken); /// /// Changes the . If currently running, may trigger a graceful restart. /// /// The new . May be modified. /// The for the operation. - /// A representing the running operation. - Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken); /// /// Restarts the watchdog. /// /// If the restart will be delayed until a reboot is detected in the active server's DMAPI and this function will retrun immediately. /// The for the operation. - /// A representing the running operation. - Task Restart(bool graceful, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Restart(bool graceful, CancellationToken cancellationToken); /// /// Stops the watchdog. /// /// If the termination will be delayed until a reboot is detected in the active server's DMAPI and this function will return immediately. /// The for the operation. - /// A representing the running operation. - Task Terminate(bool graceful, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Terminate(bool graceful, CancellationToken cancellationToken); /// /// Cancels pending graceful actions. /// /// The for the operation. - /// A representing the running operation. - Task ResetRebootState(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask ResetRebootState(CancellationToken cancellationToken); /// /// Attempt to create a process dump for DreamDaemon. /// /// The for the operation. - /// A representing the running operation. - Task CreateDump(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CreateDump(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index 13adcd702fc..4fc762046ac 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -255,7 +255,7 @@ public async ValueTask DisposeAsync() } /// - public async Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken) + public async ValueTask ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken) { using (await SemaphoreSlimContext.Lock(synchronizationSemaphore, cancellationToken)) { @@ -315,7 +315,7 @@ public async ValueTask HandleChatCommand(string commandName, str } /// - public async Task Launch(CancellationToken cancellationToken) + public async ValueTask Launch(CancellationToken cancellationToken) { if (Status != WatchdogStatus.Offline) throw new JobException(ErrorCode.WatchdogRunning); @@ -324,7 +324,7 @@ public async Task Launch(CancellationToken cancellationToken) } /// - public virtual async Task ResetRebootState(CancellationToken cancellationToken) + public virtual async ValueTask ResetRebootState(CancellationToken cancellationToken) { using (await SemaphoreSlimContext.Lock(synchronizationSemaphore, cancellationToken)) { @@ -337,7 +337,7 @@ public virtual async Task ResetRebootState(CancellationToken cancellationToken) } /// - public async Task Restart(bool graceful, CancellationToken cancellationToken) + public async ValueTask Restart(bool graceful, CancellationToken cancellationToken) { if (Status == WatchdogStatus.Offline) throw new JobException(ErrorCode.WatchdogNotRunning); @@ -398,7 +398,7 @@ public Task StopAsync(CancellationToken cancellationToken) => TerminateNoLock(false, !releaseServers, cancellationToken); /// - public async Task Terminate(bool graceful, CancellationToken cancellationToken) + public async ValueTask Terminate(bool graceful, CancellationToken cancellationToken) { using (await SemaphoreSlimContext.Lock(synchronizationSemaphore, cancellationToken)) await TerminateNoLock(graceful, !releaseServers, cancellationToken); @@ -430,10 +430,10 @@ public async ValueTask HandleRestart(Version updateVersion, bool handlerMayDelay } /// - public abstract Task InstanceRenamed(string newInstanceName, CancellationToken cancellationToken); + public abstract ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken); /// - public async Task CreateDump(CancellationToken cancellationToken) + public async ValueTask CreateDump(CancellationToken cancellationToken) { const string DumpDirectory = "ProcessDumps"; await diagnosticsIOManager.CreateDirectory(DumpDirectory, cancellationToken); diff --git a/src/Tgstation.Server.Host/Controllers/ByondController.cs b/src/Tgstation.Server.Host/Controllers/ByondController.cs index 873a9181407..92c9878d7b5 100644 --- a/src/Tgstation.Server.Host/Controllers/ByondController.cs +++ b/src/Tgstation.Server.Host/Controllers/ByondController.cs @@ -311,7 +311,7 @@ public async Task Delete([FromBody] ByondVersionDeleteRequest mod await jobManager.RegisterOperation( job, (instanceCore, databaseContextFactory, job, progressReporter, jobCancellationToken) - => instanceCore.ByondManager.DeleteVersion(progressReporter, version, jobCancellationToken).AsTask(), + => instanceCore.ByondManager.DeleteVersion(progressReporter, version, jobCancellationToken), cancellationToken); var apiResponse = job.ToApi(); diff --git a/src/Tgstation.Server.Host/Jobs/JobEntrypoint.cs b/src/Tgstation.Server.Host/Jobs/JobEntrypoint.cs index 5835675bf65..79e71b5048c 100644 --- a/src/Tgstation.Server.Host/Jobs/JobEntrypoint.cs +++ b/src/Tgstation.Server.Host/Jobs/JobEntrypoint.cs @@ -15,8 +15,8 @@ namespace Tgstation.Server.Host.Jobs /// The running . /// The for the job. /// The for the operation. - /// A representing the running operation. - public delegate Task JobEntrypoint( + /// A representing the running operation. + public delegate ValueTask JobEntrypoint( IInstanceCore instance, IDatabaseContextFactory databaseContextFactory, Job job, From dc52156e0e85b1d13cb866db787c8ee827e5a3f5 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 14:59:08 -0400 Subject: [PATCH 16/33] Even more ValueTask conversions --- .../Components/Chat/ChatManager.cs | 8 ++-- .../Components/Deployment/DmbFactory.cs | 7 ++-- .../Components/Deployment/DreamMaker.cs | 11 +++--- .../Remote/BaseRemoteDeploymentManager.cs | 37 ++++++++++--------- .../Remote/GitHubRemoteDeploymentManager.cs | 20 +++++----- .../Remote/GitLabRemoteDeploymentManager.cs | 22 +++++------ .../Remote/IRemoteDeploymentManager.cs | 26 ++++++------- .../Remote/NoOpRemoteDeploymentManager.cs | 20 +++++----- .../Components/Events/EventConsumer.cs | 2 +- .../Components/Events/IEventConsumer.cs | 4 +- .../Components/StaticFiles/Configuration.cs | 23 ++++++------ .../Components/StaticFiles/IConfiguration.cs | 28 +++++++------- .../Components/Watchdog/BasicWatchdog.cs | 4 +- .../Components/Watchdog/WatchdogBase.cs | 25 +++++++------ .../Utils/GitHub/GitHubService.cs | 12 +++--- .../GitHub/IAuthenticatedGitHubService.cs | 4 +- .../Utils/GitHub/IGitHubService.cs | 20 +++++----- .../Live/DummyGitHubService.cs | 24 ++++++------ 18 files changed, 151 insertions(+), 146 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 0231bc973e7..7c27d08d397 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -631,8 +631,8 @@ async Task RemoveProviderChannels(long connectionId, bool removeProvi /// /// The to remap channels for. /// The for the operation. - /// A representing the running operation. - async Task RemapProvider(IProvider provider, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask RemapProvider(IProvider provider, CancellationToken cancellationToken) { logger.LogTrace("Remapping channels for provider reconnection..."); IEnumerable channelsToMap; @@ -654,9 +654,9 @@ async Task RemapProvider(IProvider provider, CancellationToken cancellationToken /// The to process. If , this indicates the provider reconnected. /// If we are called recursively after remapping the provider. /// The for the operation. - /// A representing the running operation. + /// A representing the running operation. #pragma warning disable CA1502 - async Task ProcessMessage(IProvider provider, Message message, bool recursed, CancellationToken cancellationToken) + async ValueTask ProcessMessage(IProvider provider, Message message, bool recursed, CancellationToken cancellationToken) #pragma warning restore CA1502 { if (!provider.Connected) diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs index 2b6e2d12b33..b4e333a41d5 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs @@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Deployment.Remote; using Tgstation.Server.Host.Components.Events; using Tgstation.Server.Host.Database; @@ -420,7 +421,7 @@ async Task WrapThrowableTasks() { try { - await Task.WhenAll(deleteTask, deploymentJob); + await ValueTaskExtensions.WhenAll(deleteTask, deploymentJob); } catch (Exception ex) { @@ -453,8 +454,8 @@ async Task WrapThrowableTasks() ///
/// The directory to cleanup. /// The for this . - /// The deletion . - async Task DeleteCompileJobContent(string directory, CancellationToken cancellationToken) + /// The deletion . + async ValueTask DeleteCompileJobContent(string directory, CancellationToken cancellationToken) { // Then call the cleanup event, waiting here first await eventConsumer.HandleEvent(EventType.DeploymentCleanup, new List { ioManager.ResolvePath(directory) }, true, cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs index 7454f410d79..6793fdfb7ff 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs @@ -10,6 +10,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Internal; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Byond; using Tgstation.Server.Host.Components.Chat; using Tgstation.Server.Host.Components.Deployment.Remote; @@ -390,7 +391,7 @@ await databaseContextFactory.UseContext( try { - await Task.WhenAll(commentsTask, eventTask); + await ValueTaskExtensions.WhenAll(commentsTask, eventTask); } catch (Exception ex) { @@ -950,10 +951,10 @@ async Task ModifyDme(Models.CompileJob job, CancellationToken cancellationToken) /// The running . /// The associated with the . /// The that was thrown. - /// A representing the running operation. - async Task CleanupFailedCompile(Models.CompileJob job, IRemoteDeploymentManager remoteDeploymentManager, Exception exception) + /// A representing the running operation. + ValueTask CleanupFailedCompile(Models.CompileJob job, IRemoteDeploymentManager remoteDeploymentManager, Exception exception) { - async Task CleanDir() + async ValueTask CleanDir() { logger.LogTrace("Cleaning compile directory..."); var jobPath = job.DirectoryName.ToString(); @@ -970,7 +971,7 @@ async Task CleanDir() } // DCT: None available - await Task.WhenAll( + return ValueTaskExtensions.WhenAll( CleanDir(), remoteDeploymentManager.FailDeployment( job, diff --git a/src/Tgstation.Server.Host/Components/Deployment/Remote/BaseRemoteDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/Remote/BaseRemoteDeploymentManager.cs index 6a4790a62e1..db48c659ba5 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/Remote/BaseRemoteDeploymentManager.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/Remote/BaseRemoteDeploymentManager.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Logging; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Repository; using Tgstation.Server.Host.Models; @@ -49,7 +50,7 @@ protected BaseRemoteDeploymentManager( } /// - public async Task PostDeploymentComments( + public async ValueTask PostDeploymentComments( CompileJob compileJob, RevisionInformation previousRevisionInformation, RepositorySettings repositorySettings, @@ -102,7 +103,7 @@ public async Task PostDeploymentComments( removedTestMerges.Count, updatedTestMerges.Count); - var tasks = new List(addedTestMerges.Count + updatedTestMerges.Count + removedTestMerges.Count); + var tasks = new List(addedTestMerges.Count + updatedTestMerges.Count + removedTestMerges.Count); foreach (var addedTestMerge in addedTestMerges) tasks.Add( CommentOnTestMergeSource( @@ -146,11 +147,11 @@ public async Task PostDeploymentComments( cancellationToken)); if (tasks.Any()) - await Task.WhenAll(tasks); + await ValueTaskExtensions.WhenAll(tasks); } /// - public Task ApplyDeployment(CompileJob compileJob, CancellationToken cancellationToken) + public ValueTask ApplyDeployment(CompileJob compileJob, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(compileJob); @@ -161,10 +162,10 @@ public Task ApplyDeployment(CompileJob compileJob, CancellationToken cancellatio } /// - public abstract Task FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken); + public abstract ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken); /// - public Task MarkInactive(CompileJob compileJob, CancellationToken cancellationToken) + public ValueTask MarkInactive(CompileJob compileJob, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(compileJob); @@ -175,14 +176,14 @@ public Task MarkInactive(CompileJob compileJob, CancellationToken cancellationTo } /// - public abstract Task> RemoveMergedTestMerges( + public abstract ValueTask> RemoveMergedTestMerges( IRepository repository, RepositorySettings repositorySettings, RevisionInformation revisionInformation, CancellationToken cancellationToken); /// - public Task StageDeployment(CompileJob compileJob, Action activationCallback, CancellationToken cancellationToken) + public ValueTask StageDeployment(CompileJob compileJob, Action activationCallback, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(compileJob); @@ -193,7 +194,7 @@ public Task StageDeployment(CompileJob compileJob, Action activationCallba } /// - public abstract Task StartDeployment( + public abstract ValueTask StartDeployment( Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, CancellationToken cancellationToken); @@ -203,24 +204,24 @@ public abstract Task StartDeployment( ///
/// The staged . /// The for the operation. - /// A representing the running operation. - protected abstract Task StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken); + /// A representing the running operation. + protected abstract ValueTask StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken); /// /// Implementation of . /// /// The being applied. /// The for the operation. - /// A representing the running operation. - protected abstract Task ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken); + /// A representing the running operation. + protected abstract ValueTask ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken); /// /// Implementation of . /// /// The inactive . /// The for the operation. - /// A representing the running operation. - protected abstract Task MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken); + /// A representing the running operation. + protected abstract ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken); /// /// Formats a comment for a given . @@ -231,7 +232,7 @@ public abstract Task StartDeployment( /// The . /// The . /// If is new, otherwise it has been updated to a different . - /// A representing the running operation. + /// A formatted for posting a informative comment about the . protected abstract string FormatTestMerge( RepositorySettings repositorySettings, CompileJob compileJob, @@ -249,8 +250,8 @@ protected abstract string FormatTestMerge( /// The comment to post. /// The . /// The for the operation. - /// A representing the running operation. - protected abstract Task CommentOnTestMergeSource( + /// A representing the running operation. + protected abstract ValueTask CommentOnTestMergeSource( RepositorySettings repositorySettings, string remoteRepositoryOwner, string remoteRepositoryName, diff --git a/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs index aa9fc5c0a44..a31780bf214 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs @@ -55,7 +55,7 @@ public GitHubRemoteDeploymentManager( } /// - public override async Task StartDeployment( + public override async ValueTask StartDeployment( Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, CancellationToken cancellationToken) @@ -148,7 +148,7 @@ await authenticatedGitHubService.CreateDeploymentStatus( } /// - public override Task FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken) + public override ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken) => UpdateDeployment( compileJob, errorMessage, @@ -156,7 +156,7 @@ public override Task FailDeployment(CompileJob compileJob, string errorMessage, cancellationToken); /// - public override async Task> RemoveMergedTestMerges( + public override async ValueTask> RemoveMergedTestMerges( IRepository repository, RepositorySettings repositorySettings, RevisionInformation revisionInformation, @@ -191,7 +191,7 @@ public override async Task> RemoveMergedTestMerge var newList = revisionInformation.ActiveTestMerges.Select(x => x.TestMerge).ToList(); PullRequest lastMerged = null; - async Task CheckRemovePR(Task task) + async ValueTask CheckRemovePR(Task task) { var pr = await task; if (!pr.Merged) @@ -215,7 +215,7 @@ async Task CheckRemovePR(Task task) } /// - protected override Task StageDeploymentImpl( + protected override ValueTask StageDeploymentImpl( CompileJob compileJob, CancellationToken cancellationToken) => UpdateDeployment( @@ -225,7 +225,7 @@ protected override Task StageDeploymentImpl( cancellationToken); /// - protected override Task ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken) + protected override ValueTask ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken) => UpdateDeployment( compileJob, "The deployment is now live on the server.", @@ -233,7 +233,7 @@ protected override Task ApplyDeploymentImpl(CompileJob compileJob, CancellationT cancellationToken); /// - protected override Task MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken) + protected override ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken) => UpdateDeployment( compileJob, "The deployment has been superceeded.", @@ -241,7 +241,7 @@ protected override Task MarkInactiveImpl(CompileJob compileJob, CancellationToke cancellationToken); /// - protected override async Task CommentOnTestMergeSource( + protected override async ValueTask CommentOnTestMergeSource( RepositorySettings repositorySettings, string remoteRepositoryOwner, string remoteRepositoryName, @@ -302,8 +302,8 @@ protected override string FormatTestMerge( /// A description of the update. /// The new . /// The for the operation. - /// A representing the running operation. - async Task UpdateDeployment( + /// A representing the running operation. + async ValueTask UpdateDeployment( CompileJob compileJob, string description, DeploymentState deploymentState, diff --git a/src/Tgstation.Server.Host/Components/Deployment/Remote/GitLabRemoteDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/Remote/GitLabRemoteDeploymentManager.cs index 18e172c1225..3154b2ee03c 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/Remote/GitLabRemoteDeploymentManager.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/Remote/GitLabRemoteDeploymentManager.cs @@ -36,7 +36,7 @@ public GitLabRemoteDeploymentManager( } /// - public override async Task> RemoveMergedTestMerges( + public override async ValueTask> RemoveMergedTestMerges( IRepository repository, RepositorySettings repositorySettings, RevisionInformation revisionInformation, @@ -76,7 +76,7 @@ public override async Task> RemoveMergedTestMerge var newList = revisionInformation.ActiveTestMerges.Select(x => x.TestMerge).ToList(); MergeRequest lastMerged = null; - async Task CheckRemoveMR(Task task) + async ValueTask CheckRemoveMR(Task task) { var mergeRequest = await task; if (mergeRequest.State != MergeRequestState.Merged) @@ -100,30 +100,30 @@ async Task CheckRemoveMR(Task task) } /// - public override Task FailDeployment( + public override ValueTask FailDeployment( CompileJob compileJob, string errorMessage, - CancellationToken cancellationToken) => Task.CompletedTask; + CancellationToken cancellationToken) => ValueTask.CompletedTask; /// - public override Task StartDeployment( + public override ValueTask StartDeployment( Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, - CancellationToken cancellationToken) => Task.CompletedTask; + CancellationToken cancellationToken) => ValueTask.CompletedTask; /// - protected override Task ApplyDeploymentImpl( + protected override ValueTask ApplyDeploymentImpl( CompileJob compileJob, - CancellationToken cancellationToken) => Task.CompletedTask; + CancellationToken cancellationToken) => ValueTask.CompletedTask; /// - protected override Task StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken) => Task.CompletedTask; + protected override ValueTask StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken) => ValueTask.CompletedTask; /// - protected override Task MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken) => Task.CompletedTask; + protected override ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken) => ValueTask.CompletedTask; /// - protected override async Task CommentOnTestMergeSource( + protected override async ValueTask CommentOnTestMergeSource( RepositorySettings repositorySettings, string remoteRepositoryOwner, string remoteRepositoryName, diff --git a/src/Tgstation.Server.Host/Components/Deployment/Remote/IRemoteDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/Remote/IRemoteDeploymentManager.cs index ffa64bc8781..42b154ac7ef 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/Remote/IRemoteDeploymentManager.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/Remote/IRemoteDeploymentManager.cs @@ -19,8 +19,8 @@ interface IRemoteDeploymentManager /// The of the repository being deployed. /// The active . /// The for the operation. - /// A representing the running operation. - Task StartDeployment( + /// A representing the running operation. + ValueTask StartDeployment( Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, CancellationToken cancellationToken); @@ -31,8 +31,8 @@ Task StartDeployment( /// The staged . /// An optional to be called when the becomes active or is discarded with or respectively. /// The for the operation. - /// A representing the running operation. - Task StageDeployment( + /// A representing the running operation. + ValueTask StageDeployment( CompileJob compileJob, Action activationCallback, CancellationToken cancellationToken); @@ -42,8 +42,8 @@ Task StageDeployment( /// /// The being applied. /// The for the operation. - /// A representing the running operation. - Task ApplyDeployment(CompileJob compileJob, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask ApplyDeployment(CompileJob compileJob, CancellationToken cancellationToken); /// /// Fail a deployment for a given . @@ -51,8 +51,8 @@ Task StageDeployment( /// The failed . /// The error message. /// The for the operation. - /// A representing the running operation. - Task FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken); /// /// Mark the deplotment for a given as inactive. @@ -60,7 +60,7 @@ Task StageDeployment( /// The inactive . /// The for the operation. /// A representing the running operation. - Task MarkInactive(CompileJob compileJob, CancellationToken cancellationToken); + ValueTask MarkInactive(CompileJob compileJob, CancellationToken cancellationToken); /// /// Post deployment comments to the test merge ticket. @@ -71,8 +71,8 @@ Task StageDeployment( /// The GitHub repostiory owner. /// The GitHub repostiory name. /// The for the operation. - /// A representing the running operation. - Task PostDeploymentComments( + /// A representing the running operation. + ValueTask PostDeploymentComments( CompileJob compileJob, RevisionInformation previousRevisionInformation, RepositorySettings repositorySettings, @@ -87,8 +87,8 @@ Task PostDeploymentComments( /// The . /// The current . /// The for the operation. - /// A resulting in the of s that should remain the new . - Task> RemoveMergedTestMerges( + /// A resulting in the of s that should remain the new . + ValueTask> RemoveMergedTestMerges( IRepository repository, RepositorySettings repositorySettings, RevisionInformation revisionInformation, diff --git a/src/Tgstation.Server.Host/Components/Deployment/Remote/NoOpRemoteDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/Remote/NoOpRemoteDeploymentManager.cs index 0aee4358fd1..b8253d412d2 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/Remote/NoOpRemoteDeploymentManager.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/Remote/NoOpRemoteDeploymentManager.cs @@ -32,31 +32,31 @@ public NoOpRemoteDeploymentManager( } /// - public override Task FailDeployment(Models.CompileJob compileJob, string errorMessage, CancellationToken cancellationToken) + public override ValueTask FailDeployment(Models.CompileJob compileJob, string errorMessage, CancellationToken cancellationToken) { throw new NotImplementedException(); } /// - public override Task> RemoveMergedTestMerges(IRepository repository, Models.RepositorySettings repositorySettings, Models.RevisionInformation revisionInformation, CancellationToken cancellationToken) - => Task.FromResult>(Array.Empty()); + public override ValueTask> RemoveMergedTestMerges(IRepository repository, Models.RepositorySettings repositorySettings, Models.RevisionInformation revisionInformation, CancellationToken cancellationToken) + => ValueTask.FromResult>(Array.Empty()); /// - public override Task StartDeployment(IGitRemoteInformation remoteInformation, Models.CompileJob compileJob, CancellationToken cancellationToken) - => Task.CompletedTask; + public override ValueTask StartDeployment(IGitRemoteInformation remoteInformation, Models.CompileJob compileJob, CancellationToken cancellationToken) + => ValueTask.CompletedTask; /// - protected override Task ApplyDeploymentImpl(Models.CompileJob compileJob, CancellationToken cancellationToken) => Task.CompletedTask; + protected override ValueTask ApplyDeploymentImpl(Models.CompileJob compileJob, CancellationToken cancellationToken) => ValueTask.CompletedTask; /// - protected override Task CommentOnTestMergeSource( + protected override ValueTask CommentOnTestMergeSource( Models.RepositorySettings repositorySettings, string remoteRepositoryOwner, string remoteRepositoryName, string comment, int testMergeNumber, CancellationToken cancellationToken) - => Task.CompletedTask; + => ValueTask.CompletedTask; /// protected override string FormatTestMerge( @@ -69,12 +69,12 @@ protected override string FormatTestMerge( => String.Empty; /// - protected override Task MarkInactiveImpl(Models.CompileJob compileJob, CancellationToken cancellationToken) + protected override ValueTask MarkInactiveImpl(Models.CompileJob compileJob, CancellationToken cancellationToken) { throw new NotImplementedException(); } /// - protected override Task StageDeploymentImpl(Models.CompileJob compileJob, CancellationToken cancellationToken) => Task.CompletedTask; + protected override ValueTask StageDeploymentImpl(Models.CompileJob compileJob, CancellationToken cancellationToken) => ValueTask.CompletedTask; } } diff --git a/src/Tgstation.Server.Host/Components/Events/EventConsumer.cs b/src/Tgstation.Server.Host/Components/Events/EventConsumer.cs index 82f7cdb8d1f..81a0d34585d 100644 --- a/src/Tgstation.Server.Host/Components/Events/EventConsumer.cs +++ b/src/Tgstation.Server.Host/Components/Events/EventConsumer.cs @@ -31,7 +31,7 @@ public EventConsumer(IConfiguration configuration) } /// - public async Task HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken) + public async ValueTask HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(parameters); diff --git a/src/Tgstation.Server.Host/Components/Events/IEventConsumer.cs b/src/Tgstation.Server.Host/Components/Events/IEventConsumer.cs index ddd31c90e8b..7fddbb8950f 100644 --- a/src/Tgstation.Server.Host/Components/Events/IEventConsumer.cs +++ b/src/Tgstation.Server.Host/Components/Events/IEventConsumer.cs @@ -16,7 +16,7 @@ public interface IEventConsumer /// An of parameters for . /// If this event is part of the deployment pipeline. /// The for the operation. - /// A representing the running operation. - Task HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs index 087503d68c4..067869b5393 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs @@ -12,6 +12,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Response; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Events; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Extensions; @@ -198,7 +199,7 @@ public void Dispose() } /// - public async Task CopyDMFilesTo(string dmeFile, string destination, CancellationToken cancellationToken) + public async ValueTask CopyDMFilesTo(string dmeFile, string destination, CancellationToken cancellationToken) { using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken)) { @@ -236,7 +237,7 @@ public async Task CopyDMFilesTo(string dmeFile, string } /// - public async Task> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) + public async ValueTask> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) { await EnsureDirectories(cancellationToken); var path = ValidateConfigRelativePath(configurationRelativePath); @@ -283,7 +284,7 @@ void ListImpl() } /// - public async Task Read(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) + public async ValueTask Read(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) { await EnsureDirectories(cancellationToken); var path = ValidateConfigRelativePath(configurationRelativePath); @@ -393,7 +394,7 @@ void GetFileStream() } /// - public async Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) + public async ValueTask SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) { async Task> GetIgnoreFiles() { @@ -416,7 +417,7 @@ async Task> GetIgnoreFiles() IReadOnlyList ignoreFiles; - async Task SymlinkBase(bool files) + async ValueTask SymlinkBase(bool files) { Task> task; if (files) @@ -425,7 +426,7 @@ async Task SymlinkBase(bool files) task = ioManager.GetDirectories(GameStaticFilesSubdirectory, cancellationToken); var entries = await task; - await Task.WhenAll(entries.Select(async file => + await ValueTaskExtensions.WhenAll(entries.Select(async file => { var fileName = ioManager.GetFileName(file); @@ -458,12 +459,12 @@ await Task.WhenAll(entries.Select(async file => { await EnsureDirectories(cancellationToken); ignoreFiles = await GetIgnoreFiles(); - await Task.WhenAll(SymlinkBase(true), SymlinkBase(false)); + await ValueTaskExtensions.WhenAll(SymlinkBase(true), SymlinkBase(false)); } } /// - public async Task Write(string configurationRelativePath, ISystemIdentity systemIdentity, string previousHash, CancellationToken cancellationToken) + public async ValueTask Write(string configurationRelativePath, ISystemIdentity systemIdentity, string previousHash, CancellationToken cancellationToken) { await EnsureDirectories(cancellationToken); var path = ValidateConfigRelativePath(configurationRelativePath); @@ -573,7 +574,7 @@ void WriteCallback() } /// - public async Task CreateDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) + public async ValueTask CreateDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) { await EnsureDirectories(cancellationToken); var path = ValidateConfigRelativePath(configurationRelativePath); @@ -605,7 +606,7 @@ void WriteCallback() public Task StopAsync(CancellationToken cancellationToken) => EnsureDirectories(cancellationToken); /// - public async Task HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken) + public async ValueTask HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(parameters); @@ -668,7 +669,7 @@ public async Task HandleEvent(EventType eventType, IEnumerable parameter } /// - public async Task DeleteDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) + public async ValueTask DeleteDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) { await EnsureDirectories(cancellationToken); var path = ValidateConfigRelativePath(configurationRelativePath); diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs index b4ed9f59f95..59546a044ef 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs @@ -21,16 +21,16 @@ public interface IConfiguration : IComponentService, IEventConsumer, IDisposable /// The .dme file being compiled. /// Path to the destination folder. /// The for the operation. - /// A resulting in the if any. - Task CopyDMFilesTo(string dmeFile, string destination, CancellationToken cancellationToken); + /// A resulting in the if any. + ValueTask CopyDMFilesTo(string dmeFile, string destination, CancellationToken cancellationToken); /// /// Symlinks all directories in the GameData directory to . /// /// Path to the destination folder. /// The for the operation. - /// A representing the running operation. - Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken); /// /// Get s for all items in a given . @@ -38,8 +38,8 @@ public interface IConfiguration : IComponentService, IEventConsumer, IDisposable /// The relative path in the Configuration directory. /// The for the operation. If , the operation will be performed as the user of the . /// The for the operation. - /// A resulting in an of the s for the items in the directory. and will both be . will be returned if the operation failed due to access contention. - Task> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); + /// A resulting in an of the s for the items in the directory. and will both be . will be returned if the operation failed due to access contention. + ValueTask> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); /// /// Reads a given . @@ -47,8 +47,8 @@ public interface IConfiguration : IComponentService, IEventConsumer, IDisposable /// The relative path in the Configuration directory. /// The for the operation. If , the operation will be performed as the user of the . /// The for the operation. - /// A resulting in the of the file. will be returned if the operation failed due to access contention. - Task Read(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); + /// A resulting in the of the file. will be returned if the operation failed due to access contention. + ValueTask Read(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); /// /// Create an empty directory at . @@ -56,8 +56,8 @@ public interface IConfiguration : IComponentService, IEventConsumer, IDisposable /// The relative path in the Configuration directory. /// The for the operation. If , the operation will be performed as the user of the . /// The for the operation. Usage may result in partial writes. - /// A resulting in if the directory already existed, otherwise. will be returned if the operation failed due to access contention. - Task CreateDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); + /// A resulting in if the directory already existed, otherwise. will be returned if the operation failed due to access contention. + ValueTask CreateDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); /// /// Attempt to delete an empty directory at . @@ -65,8 +65,8 @@ public interface IConfiguration : IComponentService, IEventConsumer, IDisposable /// The path of the empty directory to delete. /// The for the operation. If , the operation will be performed as the user of the . /// The for the operation. - /// if the directory was empty and deleted, otherwise. will be returned if the operation failed due to access contention. - Task DeleteDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); + /// A resulting in if the directory was empty and deleted, otherwise. will be returned if the operation failed due to access contention. + ValueTask DeleteDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken); /// /// Writes to a given . @@ -75,7 +75,7 @@ public interface IConfiguration : IComponentService, IEventConsumer, IDisposable /// The for the operation. If , the operation will be performed as the user of the . /// The hash any existing file must match in order for the write to succeed. /// The for the operation. Usage may result in partial writes. - /// A resulting in the updated and associated writing . will be returned if the operation failed due to access contention. - Task Write(string configurationRelativePath, ISystemIdentity systemIdentity, string previousHash, CancellationToken cancellationToken); + /// A resulting in the updated and associated writing . will be returned if the operation failed due to access contention. + ValueTask Write(string configurationRelativePath, ISystemIdentity systemIdentity, string previousHash, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs index 4bbb5956e61..a8e574c6c42 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs @@ -202,8 +202,8 @@ protected override async Task DisposeAndNullControllersImpl() protected sealed override ISessionController GetActiveController() => Server; /// - protected override async Task InitController( - Task eventTask, + protected override async ValueTask InitController( + ValueTask eventTask, ReattachInformation reattachInfo, CancellationToken cancellationToken) { diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index 4fc762046ac..1f3190d1c47 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -13,6 +13,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Internal; using Tgstation.Server.Api.Rights; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Chat; using Tgstation.Server.Host.Components.Deployment; using Tgstation.Server.Host.Components.Deployment.Remote; @@ -452,7 +453,7 @@ public async ValueTask CreateDump(CancellationToken cancellationToken) } /// - async Task IEventConsumer.HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken) + async ValueTask IEventConsumer.HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(parameters); @@ -478,7 +479,7 @@ async Task IEventConsumer.HandleEvent(EventType eventType, IEnumerable p /// to use, if any. /// The for the operation. /// A representing the running operation. - protected abstract Task InitController(Task eventTask, ReattachInformation reattachInfo, CancellationToken cancellationToken); + protected abstract ValueTask InitController(ValueTask eventTask, ReattachInformation reattachInfo, CancellationToken cancellationToken); /// /// Launches the watchdog. @@ -488,8 +489,8 @@ async Task IEventConsumer.HandleEvent(EventType eventType, IEnumerable p /// If launch failure should be announced to chat by this function. /// to use, if any. /// The for the operation. - /// A representing the running operation. - protected async Task LaunchNoLock( + /// A representing the running operation. + protected async ValueTask LaunchNoLock( bool startMonitor, bool announce, bool announceFailure, @@ -504,7 +505,7 @@ protected async Task LaunchNoLock( throw new JobException(ErrorCode.WatchdogCompileJobCorrupted); // this is necessary, the monitor could be in it's sleep loop trying to restart, if so cancel THAT monitor and start our own with blackjack and hookers - var eventTask = Task.CompletedTask; + var eventTask = ValueTask.CompletedTask; if (announce) { Chat.QueueWatchdogMessage( @@ -532,7 +533,7 @@ protected async Task LaunchNoLock( { Logger.LogWarning(e, "Failed to start watchdog!"); var originalChatTask = eventTask; - async Task ChainEventTaskWithErrorMessage() + async ValueTask ChainEventTaskWithErrorMessage() { await originalChatTask; if (announceFailure) @@ -606,11 +607,11 @@ protected async Task CheckLaunchResult(ISessionController controller, string ser } /// - /// Call from when a reattach operation fails to attempt a fresh start. + /// Call from when a reattach operation fails to attempt a fresh start. /// /// The for the operation. /// A representing the running operation. - protected async Task ReattachFailure(CancellationToken cancellationToken) + protected async ValueTask ReattachFailure(CancellationToken cancellationToken) { // we lost the server, just restart entirely // DCT: Operation must always run @@ -619,7 +620,7 @@ protected async Task ReattachFailure(CancellationToken cancellationToken) Logger.LogWarning(FailReattachMessage); Chat.QueueWatchdogMessage(FailReattachMessage); - await InitController(Task.CompletedTask, null, cancellationToken); + await InitController(ValueTask.CompletedTask, null, cancellationToken); } /// @@ -696,12 +697,12 @@ protected async Task BeforeApplyDmb(Models.CompileJob newCompileJob, Cancellatio /// If the event should be sent to DreamDaemon. /// The for the operation. /// A representing the running operation. - protected async Task HandleEventImpl(EventType eventType, IEnumerable parameters, bool relayToSession, CancellationToken cancellationToken) + protected async ValueTask HandleEventImpl(EventType eventType, IEnumerable parameters, bool relayToSession, CancellationToken cancellationToken) { try { - var sessionEventTask = relayToSession ? ((IEventConsumer)this).HandleEvent(eventType, parameters, false, cancellationToken) : Task.CompletedTask; - await Task.WhenAll( + var sessionEventTask = relayToSession ? ((IEventConsumer)this).HandleEvent(eventType, parameters, false, cancellationToken) : ValueTask.CompletedTask; + await ValueTaskExtensions.WhenAll( eventConsumer.HandleEvent(eventType, parameters, false, cancellationToken), sessionEventTask); } diff --git a/src/Tgstation.Server.Host/Utils/GitHub/GitHubService.cs b/src/Tgstation.Server.Host/Utils/GitHub/GitHubService.cs index 053510b759c..c210cb1b547 100644 --- a/src/Tgstation.Server.Host/Utils/GitHub/GitHubService.cs +++ b/src/Tgstation.Server.Host/Utils/GitHub/GitHubService.cs @@ -46,7 +46,7 @@ public GitHubService(IGitHubClient gitHubClient, ILogger logger, } /// - public async Task CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken) + public async ValueTask CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(oAuthConfiguration); @@ -71,7 +71,7 @@ public async Task CreateOAuthAccessToken(OAuthConfiguration oAuthConfigu } /// - public async Task> GetTgsReleases(CancellationToken cancellationToken) + public async ValueTask> GetTgsReleases(CancellationToken cancellationToken) { logger.LogTrace("GetTgsReleases"); var allReleases = await gitHubClient @@ -116,7 +116,7 @@ public async Task> GetTgsReleases(CancellationToken } /// - public async Task GetUpdatesRepositoryUrl(CancellationToken cancellationToken) + public async ValueTask GetUpdatesRepositoryUrl(CancellationToken cancellationToken) { logger.LogTrace("GetUpdatesRepositoryUrl"); var repository = await gitHubClient @@ -131,7 +131,7 @@ public async Task GetUpdatesRepositoryUrl(CancellationToken cancellationTok } /// - public async Task GetCurrentUserId(CancellationToken cancellationToken) + public async ValueTask GetCurrentUserId(CancellationToken cancellationToken) { logger.LogTrace("CreateOAuthAccessToken"); @@ -162,7 +162,7 @@ public Task CommentOnIssue(string repoOwner, string repoName, string comment, in } /// - public async Task GetRepositoryId(string repoOwner, string repoName, CancellationToken cancellationToken) + public async ValueTask GetRepositoryId(string repoOwner, string repoName, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(repoOwner); @@ -181,7 +181,7 @@ public async Task GetRepositoryId(string repoOwner, string repoName, Cance } /// - public async Task CreateDeployment(NewDeployment newDeployment, string repoOwner, string repoName, CancellationToken cancellationToken) + public async ValueTask CreateDeployment(NewDeployment newDeployment, string repoOwner, string repoName, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(newDeployment); diff --git a/src/Tgstation.Server.Host/Utils/GitHub/IAuthenticatedGitHubService.cs b/src/Tgstation.Server.Host/Utils/GitHub/IAuthenticatedGitHubService.cs index f920f259124..619bcead205 100644 --- a/src/Tgstation.Server.Host/Utils/GitHub/IAuthenticatedGitHubService.cs +++ b/src/Tgstation.Server.Host/Utils/GitHub/IAuthenticatedGitHubService.cs @@ -28,8 +28,8 @@ public interface IAuthenticatedGitHubService : IGitHubService /// The owner of the target repository. /// The name of the target repository. /// The for the operation. - /// A resulting in the new deployment's ID. - Task CreateDeployment(NewDeployment newDeployment, string repoOwner, string repoName, CancellationToken cancellationToken); + /// A resulting in the new deployment's ID. + ValueTask CreateDeployment(NewDeployment newDeployment, string repoOwner, string repoName, CancellationToken cancellationToken); /// /// Create a on a target deployment. diff --git a/src/Tgstation.Server.Host/Utils/GitHub/IGitHubService.cs b/src/Tgstation.Server.Host/Utils/GitHub/IGitHubService.cs index 1776529dc12..2bc7e9c2d31 100644 --- a/src/Tgstation.Server.Host/Utils/GitHub/IGitHubService.cs +++ b/src/Tgstation.Server.Host/Utils/GitHub/IGitHubService.cs @@ -18,16 +18,16 @@ public interface IGitHubService /// Gets the of the repository designated as the updates repository. /// /// The for the operation. - /// A resulting in the of the designated updates repository. - Task GetUpdatesRepositoryUrl(CancellationToken cancellationToken); + /// A resulting in the of the designated updates repository. + ValueTask GetUpdatesRepositoryUrl(CancellationToken cancellationToken); /// /// Get all valid TGS s from the configured update source. /// /// The for the operation. - /// A resulting in a of TGS s keyed by their . + /// A resulting in a of TGS s keyed by their . /// GitHub has been known to return incomplete results from the API with this call. - Task> GetTgsReleases(CancellationToken cancellationToken); + ValueTask> GetTgsReleases(CancellationToken cancellationToken); /// /// Attempt to get an OAuth token from a given . @@ -35,8 +35,8 @@ public interface IGitHubService /// The . Must have , and set. /// The OAuth response code. /// The for the operation. - /// A resulting in a representing the returned OAuth code from GitHub on success, otherwise. - Task CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken); + /// A resulting in a representing the returned OAuth code from GitHub on success, otherwise. + ValueTask CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken); /// /// Get a target repostiory's ID. @@ -44,15 +44,15 @@ public interface IGitHubService /// The owner of the target repository. /// The name of the target repository. /// The for the operation. - /// A resulting in the target repository's ID. - Task GetRepositoryId(string repoOwner, string repoName, CancellationToken cancellationToken); + /// A resulting in the target repository's ID. + ValueTask GetRepositoryId(string repoOwner, string repoName, CancellationToken cancellationToken); /// /// Get the current user's ID. /// /// The for the operation. - /// A resulting in the current user's ID. - Task GetCurrentUserId(CancellationToken cancellationToken); + /// A resulting in the current user's ID. + ValueTask GetCurrentUserId(CancellationToken cancellationToken); /// /// Get a given . diff --git a/tests/Tgstation.Server.Tests/Live/DummyGitHubService.cs b/tests/Tgstation.Server.Tests/Live/DummyGitHubService.cs index 35f62867c9f..709b312bbfc 100644 --- a/tests/Tgstation.Server.Tests/Live/DummyGitHubService.cs +++ b/tests/Tgstation.Server.Tests/Live/DummyGitHubService.cs @@ -77,10 +77,10 @@ public Task CommentOnIssue(string repoOwner, string repoName, string comment, in return Task.CompletedTask; } - public Task CreateDeployment(NewDeployment newDeployment, string repoOwner, string repoName, CancellationToken cancellationToken) + public ValueTask CreateDeployment(NewDeployment newDeployment, string repoOwner, string repoName, CancellationToken cancellationToken) { logger.LogTrace("CreateDeployment"); - return Task.FromResult(new Random().Next()); ; + return ValueTask.FromResult(new Random().Next()); ; } public Task CreateDeploymentStatus(NewDeploymentStatus newDeploymentStatus, string repoOwner, string repoName, int deploymentId, CancellationToken cancellationToken) @@ -95,28 +95,28 @@ public Task CreateDeploymentStatus(NewDeploymentStatus newDeploymentStatus, long return Task.CompletedTask; } - public Task CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken) + public ValueTask CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken) { logger.LogTrace("CreateOAuthAccessToken"); - return Task.FromResult(cryptographySuite.GetSecureString()); + return ValueTask.FromResult(cryptographySuite.GetSecureString()); } - public Task GetCurrentUserId(CancellationToken cancellationToken) + public ValueTask GetCurrentUserId(CancellationToken cancellationToken) { logger.LogTrace("GetCurrentUserId"); - return Task.FromResult(new Random().Next()); + return ValueTask.FromResult(new Random().Next()); } - public Task GetRepositoryId(string repoOwner, string repoName, CancellationToken cancellationToken) + public ValueTask GetRepositoryId(string repoOwner, string repoName, CancellationToken cancellationToken) { logger.LogTrace("GetRepositoryId"); - return Task.FromResult(new Random().NextInt64()); + return ValueTask.FromResult(new Random().NextInt64()); } - public Task GetUpdatesRepositoryUrl(CancellationToken cancellationToken) + public ValueTask GetUpdatesRepositoryUrl(CancellationToken cancellationToken) { logger.LogTrace("GetUpdatesRepositoryUrl"); - return Task.FromResult(new Uri("https://github.com/tgstation/tgstation-server")); + return ValueTask.FromResult(new Uri("https://github.com/tgstation/tgstation-server")); } public Task GetPullRequest(string repoOwner, string repoName, int pullRequestNumber, CancellationToken cancellationToken) @@ -125,10 +125,10 @@ public Task GetPullRequest(string repoOwner, string repoName, int p return Task.FromResult(testPr); } - public Task> GetTgsReleases(CancellationToken cancellationToken) + public ValueTask> GetTgsReleases(CancellationToken cancellationToken) { logger.LogTrace("GetTgsReleases"); - return Task.FromResult(releasesDictionary); + return ValueTask.FromResult(releasesDictionary); } } } From 64b7526f7382a05f201ec72852292df8e2e6630c Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 15:05:30 -0400 Subject: [PATCH 17/33] Yet even more ValueTask conversions --- .../Repository/DefaultGitRemoteFeatures.cs | 2 +- .../Repository/GitHubRemoteFeatures.cs | 2 +- .../Repository/GitLabRemoteFeatures.cs | 2 +- .../Repository/GitRemoteFeaturesBase.cs | 6 ++-- .../IGitRemoteAdditionalInformation.cs | 4 +-- .../Repository/ILibGit2RepositoryFactory.cs | 4 +-- .../Components/Repository/IRepository.cs | 28 +++++++++---------- .../Repository/LibGit2RepositoryFactory.cs | 2 +- .../Components/Repository/Repository.cs | 16 +++++------ 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Repository/DefaultGitRemoteFeatures.cs b/src/Tgstation.Server.Host/Components/Repository/DefaultGitRemoteFeatures.cs index e379ae233a1..ead4007720f 100644 --- a/src/Tgstation.Server.Host/Components/Repository/DefaultGitRemoteFeatures.cs +++ b/src/Tgstation.Server.Host/Components/Repository/DefaultGitRemoteFeatures.cs @@ -27,7 +27,7 @@ sealed class DefaultGitRemoteFeatures : IGitRemoteFeatures public string RemoteRepositoryName => null; /// - public Task GetTestMerge( + public ValueTask GetTestMerge( TestMergeParameters parameters, Api.Models.Internal.RepositorySettings repositorySettings, CancellationToken cancellationToken) => throw new NotSupportedException(); diff --git a/src/Tgstation.Server.Host/Components/Repository/GitHubRemoteFeatures.cs b/src/Tgstation.Server.Host/Components/Repository/GitHubRemoteFeatures.cs index ecbda4c74ce..6e5d5c4ec06 100644 --- a/src/Tgstation.Server.Host/Components/Repository/GitHubRemoteFeatures.cs +++ b/src/Tgstation.Server.Host/Components/Repository/GitHubRemoteFeatures.cs @@ -56,7 +56,7 @@ public GitHubRemoteFeatures(IGitHubServiceFactory gitHubServiceFactory, ILogger< } /// - protected override async Task GetTestMergeImpl( + protected override async ValueTask GetTestMergeImpl( TestMergeParameters parameters, RepositorySettings repositorySettings, CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Components/Repository/GitLabRemoteFeatures.cs b/src/Tgstation.Server.Host/Components/Repository/GitLabRemoteFeatures.cs index 236c1251127..def1adbaaf6 100644 --- a/src/Tgstation.Server.Host/Components/Repository/GitLabRemoteFeatures.cs +++ b/src/Tgstation.Server.Host/Components/Repository/GitLabRemoteFeatures.cs @@ -51,7 +51,7 @@ public GitLabRemoteFeatures(ILogger logger, Uri remoteUrl) } /// - protected override async Task GetTestMergeImpl( + protected override async ValueTask GetTestMergeImpl( TestMergeParameters parameters, RepositorySettings repositorySettings, CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Components/Repository/GitRemoteFeaturesBase.cs b/src/Tgstation.Server.Host/Components/Repository/GitRemoteFeaturesBase.cs index a1ec955e4d7..1b1c5337afb 100644 --- a/src/Tgstation.Server.Host/Components/Repository/GitRemoteFeaturesBase.cs +++ b/src/Tgstation.Server.Host/Components/Repository/GitRemoteFeaturesBase.cs @@ -54,7 +54,7 @@ public GitRemoteFeaturesBase(ILogger logger, Uri remoteUr } /// - public async Task GetTestMerge( + public async ValueTask GetTestMerge( TestMergeParameters parameters, RepositorySettings repositorySettings, CancellationToken cancellationToken) @@ -85,8 +85,8 @@ public GitRemoteFeaturesBase(ILogger logger, Uri remoteUr /// The . /// The . /// The for the operation. - /// A resulting in the of the . - protected abstract Task GetTestMergeImpl( + /// A resulting in the of the . + protected abstract ValueTask GetTestMergeImpl( TestMergeParameters parameters, RepositorySettings repositorySettings, CancellationToken cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/Repository/IGitRemoteAdditionalInformation.cs b/src/Tgstation.Server.Host/Components/Repository/IGitRemoteAdditionalInformation.cs index f859817565f..ffead020f9c 100644 --- a/src/Tgstation.Server.Host/Components/Repository/IGitRemoteAdditionalInformation.cs +++ b/src/Tgstation.Server.Host/Components/Repository/IGitRemoteAdditionalInformation.cs @@ -17,9 +17,9 @@ public interface IGitRemoteAdditionalInformation : IGitRemoteInformation /// The . /// The . /// The for the operation. - /// A resulting in the of the . + /// A resulting in the of the . /// and will be unset. - Task GetTestMerge( + ValueTask GetTestMerge( TestMergeParameters parameters, RepositorySettings repositorySettings, CancellationToken cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs b/src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs index b03048ccf66..34b8c566691 100644 --- a/src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs +++ b/src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs @@ -22,8 +22,8 @@ interface ILibGit2RepositoryFactory : ICredentialsProvider /// /// The full path to the . /// The for the operation. - /// A resulting in the loaded . - Task CreateFromPath(string path, CancellationToken cancellationToken); + /// A resulting in the loaded . + ValueTask CreateFromPath(string path, CancellationToken cancellationToken); /// /// Clone a remote . diff --git a/src/Tgstation.Server.Host/Components/Repository/IRepository.cs b/src/Tgstation.Server.Host/Components/Repository/IRepository.cs index 07c29dc220f..5cce4208ea2 100644 --- a/src/Tgstation.Server.Host/Components/Repository/IRepository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/IRepository.cs @@ -49,8 +49,8 @@ public interface IRepository : IGitRemoteAdditionalInformation, IDisposable /// If a submodule update should be attempted after the merge. /// The to report progress of the operation. /// The for the operation. - /// A representing the running operation. - Task CheckoutObject( + /// A representing the running operation. + ValueTask CheckoutObject( string committish, string username, string password, @@ -69,8 +69,8 @@ Task CheckoutObject( /// If a submodule update should be attempted after the merge. /// The to report progress of the operation. /// The for the operation. - /// A resulting in the . - Task AddTestMerge( + /// A resulting in the . + ValueTask AddTestMerge( TestMergeParameters testMergeParameters, string committerName, string committerEmail, @@ -88,8 +88,8 @@ Task AddTestMerge( /// The password to fetch from the origin repository. /// If any events created should be marked as part of the deployment pipeline. /// The for the operation. - /// A representing the running operation. - Task FetchOrigin( + /// A representing the running operation. + ValueTask FetchOrigin( JobProgressReporter progressReporter, string username, string password, @@ -105,8 +105,8 @@ Task FetchOrigin( /// If a submodule update should be attempted after the merge. /// If any events created should be marked as part of the deployment pipeline. /// The for the operation. - /// A resulting in the SHA of the new HEAD. - Task ResetToOrigin( + /// A resulting in the SHA of the new HEAD. + ValueTask ResetToOrigin( JobProgressReporter progressReporter, string username, string password, @@ -131,8 +131,8 @@ Task ResetToOrigin( /// The e-mail of the merge committer. /// If any events created should be marked as part of the deployment pipeline. /// The for the operation. - /// A resulting in a representing the merge result that is after a fast forward, on a merge or up to date, on a conflict. - Task MergeOrigin( + /// A resulting in a representing the merge result that is after a fast forward, on a merge or up to date, on a conflict. + ValueTask MergeOrigin( JobProgressReporter progressReporter, string committerName, string committerEmail, @@ -150,8 +150,8 @@ Task ResetToOrigin( /// If the synchronizations should be made to the tracked reference as opposed to a temporary branch. /// If any events created should be marked as part of the deployment pipeline. /// The for the operation. - /// A resulting in if commits were pushed to the tracked origin reference, otherwise. - Task Sychronize( + /// A resulting in if commits were pushed to the tracked origin reference, otherwise. + ValueTask Sychronize( JobProgressReporter progressReporter, string username, string password, @@ -166,8 +166,8 @@ Task Sychronize( /// /// The path to copy repository contents to. /// The for the operation. - /// A representing the running operation. - Task CopyTo(string path, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CopyTo(string path, CancellationToken cancellationToken); /// /// Check if a given is a parent of the current . diff --git a/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs b/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs index 2bbc60cccde..83011a61b1a 100644 --- a/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs +++ b/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs @@ -38,7 +38,7 @@ public void CreateInMemory() } /// - public async Task CreateFromPath(string path, CancellationToken cancellationToken) + public async ValueTask CreateFromPath(string path, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(path); diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs index 2748e5ec6c3..a7dc2486921 100644 --- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs @@ -181,7 +181,7 @@ public void Dispose() /// #pragma warning disable CA1506 // TODO: Decomplexify - public async Task AddTestMerge( + public async ValueTask AddTestMerge( TestMergeParameters testMergeParameters, string committerName, string committerEmail, @@ -384,7 +384,7 @@ await eventConsumer.HandleEvent( #pragma warning restore CA1506 /// - public async Task CheckoutObject( + public async ValueTask CheckoutObject( string committish, string username, string password, @@ -419,7 +419,7 @@ await UpdateSubmodules( } /// - public async Task FetchOrigin( + public async ValueTask FetchOrigin( JobProgressReporter progressReporter, string username, string password, @@ -466,7 +466,7 @@ await Task.Factory.StartNew( } /// - public async Task ResetToOrigin( + public async ValueTask ResetToOrigin( JobProgressReporter progressReporter, string username, string password, @@ -522,7 +522,7 @@ public Task ResetToSha(string sha, JobProgressReporter progressReporter, Cancell TaskScheduler.Current); /// - public async Task CopyTo(string path, CancellationToken cancellationToken) + public async ValueTask CopyTo(string path, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(path); logger.LogTrace("Copying to {path}...", path); @@ -557,7 +557,7 @@ public Task GetOriginSha(CancellationToken cancellationToken) => Task.Fa TaskScheduler.Current); /// - public async Task MergeOrigin( + public async ValueTask MergeOrigin( JobProgressReporter progressReporter, string committerName, string committerEmail, @@ -636,7 +636,7 @@ await eventConsumer.HandleEvent( } /// - public async Task Sychronize( + public async ValueTask Sychronize( JobProgressReporter progressReporter, string username, string password, @@ -828,7 +828,7 @@ public Task ShaIsParent(string sha, CancellationToken cancellationToken) = TaskScheduler.Current); /// - public Task GetTestMerge( + public ValueTask GetTestMerge( TestMergeParameters parameters, RepositorySettings repositorySettings, CancellationToken cancellationToken) => gitRemoteFeatures.GetTestMerge( From 1db8ce737dc18c9a09dde7f8c985982e5b8c110b Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 15:14:11 -0400 Subject: [PATCH 18/33] Guess what? More ValueTask conversions! --- .../Repository/RepositoryUpdateService.cs | 4 ++-- .../Session/ISessionControllerFactory.cs | 8 ++++---- .../Components/Session/ISessionPersistor.cs | 4 ++-- .../Components/Session/SessionController.cs | 4 ++-- .../Components/Session/SessionControllerFactory.cs | 14 +++++++------- .../Components/Session/SessionPersistor.cs | 2 +- .../Components/Watchdog/BasicWatchdog.cs | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs index 93339cc96fa..418dc9462d5 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs @@ -79,8 +79,8 @@ public RepositoryUpdateService( /// The last known origin commit SHA of the if any. /// An optional to receive the loaded . /// The for the operation. - /// A resulting in if the was modified in a way that requires saving, otherwise. - public static async Task LoadRevisionInformation( + /// A resulting in if the was modified in a way that requires saving, otherwise. + public static async ValueTask LoadRevisionInformation( IRepository repository, IDatabaseContext databaseContext, ILogger logger, diff --git a/src/Tgstation.Server.Host/Components/Session/ISessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/ISessionControllerFactory.cs index 7e99d8e09ae..b5bbf07f902 100644 --- a/src/Tgstation.Server.Host/Components/Session/ISessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/ISessionControllerFactory.cs @@ -20,8 +20,8 @@ interface ISessionControllerFactory /// The to use. will be updated with the minumum required security level for the launch. /// If the should only validate the DMAPI then exit. /// The for the operation. - /// A resulting in a new . - Task LaunchNew( + /// A resulting in a new . + ValueTask LaunchNew( IDmbProvider dmbProvider, IByondExecutableLock currentByondLock, DreamDaemonLaunchParameters launchParameters, @@ -33,8 +33,8 @@ Task LaunchNew( /// /// The to use. /// The for the operation. - /// A resulting in a new on success or on failure to reattach. - Task Reattach( + /// A resulting in a new on success or on failure to reattach. + ValueTask Reattach( ReattachInformation reattachInformation, CancellationToken cancellationToken); } diff --git a/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs b/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs index 97b9065b474..9e088bd7b14 100644 --- a/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs +++ b/src/Tgstation.Server.Host/Components/Session/ISessionPersistor.cs @@ -20,8 +20,8 @@ public interface ISessionPersistor /// Load a saved . /// /// The for the operation. - /// A resulting in the stored if any. - Task Load(CancellationToken cancellationToken); + /// A resulting in the stored if any. + ValueTask Load(CancellationToken cancellationToken); /// /// Clear any stored . diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs index f687e9b6c45..f4b340e4f52 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs @@ -236,7 +236,7 @@ async Task Wrap() /// The for the . /// The for the . /// The value of . - /// The returning a to be run after the ends. + /// The returning a to be run after the ends. /// The optional time to wait before failing the . /// If this is a reattached session. /// If this is a DMAPI validation session. @@ -252,7 +252,7 @@ public SessionController( IAssemblyInformationProvider assemblyInformationProvider, IAsyncDelayer asyncDelayer, ILogger logger, - Func postLifetimeCallback, + Func postLifetimeCallback, uint? startupTimeout, bool reattached, bool apiValidate) diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index 96228c3c327..97fee0a95eb 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -239,7 +239,7 @@ public SessionControllerFactory( } /// - public async Task LaunchNew( + public async ValueTask LaunchNew( IDmbProvider dmbProvider, IByondExecutableLock currentByondLock, DreamDaemonLaunchParameters launchParameters, @@ -395,7 +395,7 @@ public async Task LaunchNew( } /// - public async Task Reattach( + public async ValueTask Reattach( ReattachInformation reattachInformation, CancellationToken cancellationToken) { @@ -446,7 +446,7 @@ public async Task Reattach( assemblyInformationProvider, asyncDelayer, loggerFactory.CreateLogger(), - () => Task.CompletedTask, + () => ValueTask.CompletedTask, null, true, false); @@ -487,8 +487,8 @@ public async Task Reattach( /// The path to log DreamDaemon output to. /// If we are only validating the DMAPI then exiting. /// The for the operation. - /// A resulting in the DreamDaemon . - async Task CreateDreamDaemonProcess( + /// A resulting in the DreamDaemon . + async ValueTask CreateDreamDaemonProcess( IDmbProvider dmbProvider, ITopicClient byondTopicSender, IByondExecutableLock byondLock, @@ -578,8 +578,8 @@ await eventConsumer.HandleEvent( /// If DreamDaemon was launched with CLI capabilities. /// If , will be deleted. /// The for the operation. - /// A representing the running operation. - async Task LogDDOutput(IProcess process, string outputFilePath, bool cliSupported, bool preserveFile, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask LogDDOutput(IProcess process, string outputFilePath, bool cliSupported, bool preserveFile, CancellationToken cancellationToken) { try { diff --git a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs index d452f4fac6f..5b44e93c540 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs @@ -90,7 +90,7 @@ public ValueTask Save(ReattachInformation reattachInformation, CancellationToken }); /// - public async Task Load(CancellationToken cancellationToken) + public async ValueTask Load(CancellationToken cancellationToken) { Models.ReattachInformation result = null; TimeSpan? topicTimeout = null; diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs index a8e574c6c42..7e181bf7ed5 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs @@ -217,7 +217,7 @@ protected override async ValueTask InitController( // start the alpha server task, either by launch a new process or attaching to an existing one // The tasks returned are mainly for writing interop files to the directories among other things and should generally never fail // The tasks pertaining to server startup times are in the ISessionControllers - Task serverLaunchTask; + ValueTask serverLaunchTask; if (!reattachInProgress) { Logger.LogTrace("Initializing controller with CompileJob {compileJobId}...", dmbToUse.CompileJob.Id); From fc52eae7ca7856013de9aee2f520132671316da2 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 15:19:10 -0400 Subject: [PATCH 19/33] Watchdog ValueTask conversions --- .../Components/Watchdog/BasicWatchdog.cs | 18 ++++----- .../Components/Watchdog/PosixWatchdog.cs | 4 +- .../Components/Watchdog/WatchdogBase.cs | 38 +++++++++---------- .../Components/Watchdog/WindowsWatchdog.cs | 12 +++--- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs index 7e181bf7ed5..fa9159527d4 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs @@ -104,7 +104,7 @@ public sealed override ValueTask InstanceRenamed(string newInstanceName, Cancell => Server?.InstanceRenamed(newInstanceName, cancellationToken) ?? ValueTask.CompletedTask; /// - protected override async Task HandleMonitorWakeup(MonitorActivationReason reason, CancellationToken cancellationToken) + protected override async ValueTask HandleMonitorWakeup(MonitorActivationReason reason, CancellationToken cancellationToken) { switch (reason) { @@ -187,7 +187,7 @@ protected override async Task HandleMonitorWakeup(MonitorActivati } /// - protected override async Task DisposeAndNullControllersImpl() + protected override async ValueTask DisposeAndNullControllersImpl() { var disposeTask = Server?.DisposeAsync(); gracefulRebootRequired = false; @@ -286,20 +286,20 @@ protected virtual ValueTask SessionStartupPersist(CancellationToken cancellation /// Handler for when the is . /// /// The for the operation. - /// A resulting in the to take. - protected virtual Task HandleNormalReboot(CancellationToken cancellationToken) + /// A resulting in the to take. + protected virtual ValueTask HandleNormalReboot(CancellationToken cancellationToken) { var settingsUpdatePending = ActiveLaunchParameters != LastLaunchParameters; var result = settingsUpdatePending ? MonitorAction.Restart : MonitorAction.Continue; - return Task.FromResult(result); + return ValueTask.FromResult(result); } /// /// Handler for . /// /// The for the operation. - /// A representing the running operation. - protected virtual async Task HandleNewDmbAvailable(CancellationToken cancellationToken) + /// A representing the running operation. + protected virtual async ValueTask HandleNewDmbAvailable(CancellationToken cancellationToken) { gracefulRebootRequired = true; if (Server.CompileJob.DMApiVersion == null) @@ -317,7 +317,7 @@ protected virtual async Task HandleNewDmbAvailable(CancellationToken cancellatio /// /// The to be launched. Will not be disposed by this function. /// The for the operation. - /// A resulting in the modified to be used. - protected virtual Task PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken) => Task.FromResult(dmbToUse); + /// A resulting in the modified to be used. + protected virtual ValueTask PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken) => ValueTask.FromResult(dmbToUse); } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs index 044ef3f1ef8..841f9036776 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs @@ -78,10 +78,10 @@ public PosixWatchdog( } /// - protected override Task ApplyInitialDmb(CancellationToken cancellationToken) + protected override ValueTask ApplyInitialDmb(CancellationToken cancellationToken) { // not necessary to hold initial .dmb on Linux because of based inode deletes - return Task.CompletedTask; + return ValueTask.CompletedTask; } } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index 1f3190d1c47..a7eb583a7d3 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -568,8 +568,8 @@ async ValueTask ChainEventTaskWithErrorMessage() /// /// Stops . Doesn't kill the servers. /// - /// if the monitor was running, otherwise. - protected async Task StopMonitor() + /// A resulting in if the monitor was running, otherwise. + protected async ValueTask StopMonitor() { Logger.LogTrace("StopMonitor"); if (monitorTask == null) @@ -590,8 +590,8 @@ protected async Task StopMonitor() /// The to checkou. /// The name of the server being checked. /// The for the operation. - /// A representing the running operation. - protected async Task CheckLaunchResult(ISessionController controller, string serverName, CancellationToken cancellationToken) + /// A representing the running operation. + protected async ValueTask CheckLaunchResult(ISessionController controller, string serverName, CancellationToken cancellationToken) { var launchResult = await controller.LaunchResult.WaitAsync(cancellationToken); @@ -610,7 +610,7 @@ protected async Task CheckLaunchResult(ISessionController controller, string ser /// Call from when a reattach operation fails to attempt a fresh start. /// /// The for the operation. - /// A representing the running operation. + /// A representing the running operation. protected async ValueTask ReattachFailure(CancellationToken cancellationToken) { // we lost the server, just restart entirely @@ -626,15 +626,15 @@ protected async ValueTask ReattachFailure(CancellationToken cancellationToken) /// /// Call and null the fields for all s. /// - /// A representing the running operation. - protected abstract Task DisposeAndNullControllersImpl(); + /// A representing the running operation. + protected abstract ValueTask DisposeAndNullControllersImpl(); /// /// Wrapper for under a locked context. /// /// The for the operation. - /// A representing the running operation. - protected async Task DisposeAndNullControllers(CancellationToken cancellationToken) + /// A representing the running operation. + protected async ValueTask DisposeAndNullControllers(CancellationToken cancellationToken) { Logger.LogTrace("DisposeAndNullControllers"); using (await SemaphoreSlimContext.Lock(controllerDisposeSemaphore, cancellationToken)) @@ -656,8 +656,8 @@ protected async Task DisposeAndNullControllers(CancellationToken cancellationTok /// /// The that caused the invocation. Will never be . /// The for the operation. - /// A resulting in the to take. - protected abstract Task HandleMonitorWakeup( + /// A resulting in the to take. + protected abstract ValueTask HandleMonitorWakeup( MonitorActivationReason activationReason, CancellationToken cancellationToken); @@ -666,8 +666,8 @@ protected abstract Task HandleMonitorWakeup( /// /// The new being applied. /// The for the operation. - /// A representing the running operation. - protected async Task BeforeApplyDmb(Models.CompileJob newCompileJob, CancellationToken cancellationToken) + /// A representing the running operation. + protected async ValueTask BeforeApplyDmb(Models.CompileJob newCompileJob, CancellationToken cancellationToken) { if (newCompileJob.Id == ActiveCompileJob?.Id) { @@ -696,7 +696,7 @@ protected async Task BeforeApplyDmb(Models.CompileJob newCompileJob, Cancellatio /// An of parameters for . /// If the event should be sent to DreamDaemon. /// The for the operation. - /// A representing the running operation. + /// A representing the running operation. protected async ValueTask HandleEventImpl(EventType eventType, IEnumerable parameters, bool relayToSession, CancellationToken cancellationToken) { try @@ -716,8 +716,8 @@ await ValueTaskExtensions.WhenAll( /// Attempt to restart the monitor from scratch. /// /// The for the operation. - /// A representing the running operation. - async Task MonitorRestart(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask MonitorRestart(CancellationToken cancellationToken) { Logger.LogTrace("Monitor restart!"); @@ -784,7 +784,7 @@ Task InitialCheckDmbUpdated(CompileJob currentCompileJob) /// The main loop of the watchdog. Ayschronously waits for events to occur and then responds to them. /// /// The for the operation. - /// A representing the running operation. + /// A representing the running operation. #pragma warning disable CA1502 async Task MonitorLifetimes(CancellationToken cancellationToken) { @@ -1043,8 +1043,8 @@ async Task TerminateNoLock(bool graceful, bool announce, CancellationToken cance /// Handles a watchdog health check. /// /// The for the operation. - /// A resulting in the next to take. - async Task HandleHealthCheck(CancellationToken cancellationToken) + /// A resulting in the next to take. + async ValueTask HandleHealthCheck(CancellationToken cancellationToken) { Logger.LogTrace("Sending health check to active server..."); var activeServer = GetActiveController(); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs index 50980da257d..fd1ab5fb182 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs @@ -125,7 +125,7 @@ public WindowsWatchdog( } /// - protected override async Task DisposeAndNullControllersImpl() + protected override async ValueTask DisposeAndNullControllersImpl() { await base.DisposeAndNullControllersImpl(); @@ -138,7 +138,7 @@ protected override async Task DisposeAndNullControllersImpl() } /// - protected override async Task HandleNormalReboot(CancellationToken cancellationToken) + protected override async ValueTask HandleNormalReboot(CancellationToken cancellationToken) { if (pendingSwappable != null) { @@ -219,7 +219,7 @@ async Task CleanupLingeringDeployment() } /// - protected override async Task HandleNewDmbAvailable(CancellationToken cancellationToken) + protected override async ValueTask HandleNewDmbAvailable(CancellationToken cancellationToken) { IDmbProvider compileJobProvider = DmbFactory.LockNextDmb(1); bool canSeamlesslySwap = true; @@ -275,7 +275,7 @@ protected override async Task HandleNewDmbAvailable(CancellationToken cancellati } /// - protected sealed override async Task PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken) + protected sealed override async ValueTask PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken) { if (ActiveSwappable != null) throw new InvalidOperationException("Expected activeSwappable to be null!"); @@ -305,7 +305,7 @@ protected sealed override async Task PrepServerForLaunch(IDmbProvi /// /// The for the operation. /// A representing the running operation. - protected virtual async Task ApplyInitialDmb(CancellationToken cancellationToken) + protected virtual async ValueTask ApplyInitialDmb(CancellationToken cancellationToken) { Server.ReattachInformation.InitialDmb = await DmbFactory.FromCompileJob(Server.CompileJob, cancellationToken); } @@ -318,7 +318,7 @@ protected override async ValueTask SessionStartupPersist(CancellationToken cance } /// - protected override async Task HandleMonitorWakeup(MonitorActivationReason reason, CancellationToken cancellationToken) + protected override async ValueTask HandleMonitorWakeup(MonitorActivationReason reason, CancellationToken cancellationToken) { var result = await base.HandleMonitorWakeup(reason, cancellationToken); if (reason == MonitorActivationReason.ActiveServerStartup) From 8166cd3629f2806ab557f8d1a722480ab9c874da Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 15:53:35 -0400 Subject: [PATCH 20/33] ValueTask conversion for controllers --- .../Controllers/AdministrationController.cs | 24 ++++++------- .../Controllers/ApiController.cs | 34 +++++++++--------- .../Controllers/BridgeController.cs | 4 +-- .../Controllers/ByondController.cs | 24 ++++++------- .../Controllers/ChatController.cs | 24 ++++++------- .../ComponentInterfacingController.cs | 8 ++--- .../Controllers/ConfigurationController.cs | 24 ++++++------- .../Controllers/DreamDaemonController.cs | 28 +++++++-------- .../Controllers/DreamMakerController.cs | 22 ++++++------ .../Controllers/HomeController.cs | 8 ++--- .../Controllers/InstanceController.cs | 36 +++++++++---------- .../InstancePermissionSetController.cs | 22 ++++++------ .../Controllers/JobController.cs | 26 +++++++------- .../Controllers/RepositoryController.cs | 20 +++++------ .../Controllers/SwarmController.cs | 18 +++++----- .../Controllers/TransferController.cs | 8 ++--- .../Controllers/UserController.cs | 22 ++++++------ .../Controllers/UserGroupController.cs | 22 ++++++------ .../FileTransferStreamHandlerExtensions.cs | 4 +-- .../Swarm/SwarmRpcMapper.cs | 13 +++++-- .../Swarm/TestableSwarmNode.cs | 6 ++-- 21 files changed, 203 insertions(+), 194 deletions(-) diff --git a/src/Tgstation.Server.Host/Controllers/AdministrationController.cs b/src/Tgstation.Server.Host/Controllers/AdministrationController.cs index 636aa182a2c..b742a2ae18a 100644 --- a/src/Tgstation.Server.Host/Controllers/AdministrationController.cs +++ b/src/Tgstation.Server.Host/Controllers/AdministrationController.cs @@ -126,7 +126,7 @@ public AdministrationController( /// Get server information. /// /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Retrieved data successfully. /// The GitHub API rate limit was hit. See response header Retry-After. /// A GitHub API error occurred. See error message for details. @@ -135,7 +135,7 @@ public AdministrationController( [ProducesResponseType(typeof(AdministrationResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 424)] [ProducesResponseType(typeof(ErrorMessageResponse), 429)] - public async Task Read(CancellationToken cancellationToken) + public async ValueTask Read(CancellationToken cancellationToken) { try { @@ -188,7 +188,7 @@ public async Task Read(CancellationToken cancellationToken) /// /// The . /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Update has been started successfully. /// The requested release version could not be found in the target GitHub repository. /// Upgrade operations are unavailable due to the launch configuration of TGS. @@ -201,7 +201,7 @@ public async Task Read(CancellationToken cancellationToken) [ProducesResponseType(typeof(ErrorMessageResponse), 422)] [ProducesResponseType(typeof(ErrorMessageResponse), 424)] [ProducesResponseType(typeof(ErrorMessageResponse), 429)] - public async Task Update([FromBody] ServerUpdateRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] ServerUpdateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -232,14 +232,14 @@ public async Task Update([FromBody] ServerUpdateRequest model, Ca /// /// Attempts to restart the server. /// - /// A resulting in the of the request. + /// A resulting in the of the request. /// Restart begun successfully. /// Restart operations are unavailable due to the launch configuration of TGS. [HttpDelete] [TgsAuthorize(AdministrationRights.RestartHost)] [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 422)] - public async Task Delete() + public async ValueTask Delete() { try { @@ -264,14 +264,14 @@ public async Task Delete() /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Listed logs successfully. /// An IO error occurred while listing. [HttpGet(Routes.Logs)] [TgsAuthorize(AdministrationRights.DownloadLogs)] [ProducesResponseType(typeof(PaginatedResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] - public Task ListLogs([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask ListLogs([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( async () => { @@ -317,14 +317,14 @@ public Task ListLogs([FromQuery] int? page, [FromQuery] int? page /// /// The path to download. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Downloaded successfully. /// An IO error occurred while downloading. [HttpGet(Routes.Logs + "/{*path}")] [TgsAuthorize(AdministrationRights.DownloadLogs)] [ProducesResponseType(typeof(LogFileResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] - public async Task GetLog(string path, CancellationToken cancellationToken) + public async ValueTask GetLog(string path, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(path); @@ -369,8 +369,8 @@ public async Task GetLog(string path, CancellationToken cancellat /// The being updated to. /// If an upload is being attempted. /// The for the operation. - /// A resulting in the of the request. - async Task AttemptInitiateUpdate(Version newVersion, bool attemptingUpload, CancellationToken cancellationToken) + /// A resulting in the of the request. + async ValueTask AttemptInitiateUpdate(Version newVersion, bool attemptingUpload, CancellationToken cancellationToken) { IFileUploadTicket uploadTicket = attemptingUpload ? fileTransferService.CreateUpload(FileUploadStreamKind.None) diff --git a/src/Tgstation.Server.Host/Controllers/ApiController.cs b/src/Tgstation.Server.Host/Controllers/ApiController.cs index b3d26b709f1..c0f37fbf82c 100644 --- a/src/Tgstation.Server.Host/Controllers/ApiController.cs +++ b/src/Tgstation.Server.Host/Controllers/ApiController.cs @@ -257,9 +257,9 @@ protected ObjectResult RateLimit(RateLimitExceededException rateLimitException) /// Performs validation a request. ///
/// The for the operation. - /// A resulting in an appropriate on validation failure, otherwise. - protected virtual Task ValidateRequest(CancellationToken cancellationToken) - => Task.FromResult(null); + /// A resulting in an appropriate on validation failure, otherwise. + protected virtual ValueTask ValidateRequest(CancellationToken cancellationToken) + => ValueTask.FromResult(null); /// /// Response for missing/Invalid headers. @@ -299,10 +299,10 @@ protected IActionResult HeadersIssue(bool ignoreMissingAuth) /// The requested page from the query. /// The requested page size from the query. /// The for the operation. - /// A resulting in the for the operation. - protected Task Paginated( - Func>> queryGenerator, - Func resultTransformer, + /// A resulting in the for the operation. + protected ValueTask Paginated( + Func>> queryGenerator, + Func resultTransformer, int? pageQuery, int? pageSizeQuery, CancellationToken cancellationToken) => PaginatedImpl( @@ -317,15 +317,15 @@ protected Task Paginated( /// /// The of model being generated. /// The of model being returned. - /// A resulting in a resulting in the generated . + /// A resulting in a resulting in the generated . /// A to transform the s after being queried. /// The requested page from the query. /// The requested page size from the query. /// The for the operation. - /// A resulting in the for the operation. - protected Task Paginated( - Func>> queryGenerator, - Func resultTransformer, + /// A resulting in the for the operation. + protected ValueTask Paginated( + Func>> queryGenerator, + Func resultTransformer, int? pageQuery, int? pageSizeQuery, CancellationToken cancellationToken) @@ -342,15 +342,15 @@ protected Task Paginated( ///
/// The of model being generated. If different from , must implement for . /// The of model being returned. - /// A resulting in a resulting in the generated . + /// A resulting in a resulting in the generated . /// A to transform the s after being queried. /// The requested page from the query. /// The requested page size from the query. /// The for the operation. - /// A resulting in the for the operation. - async Task PaginatedImpl( - Func>> queryGenerator, - Func resultTransformer, + /// A resulting in the for the operation. + async ValueTask PaginatedImpl( + Func>> queryGenerator, + Func resultTransformer, int? pageQuery, int? pageSizeQuery, CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Controllers/BridgeController.cs b/src/Tgstation.Server.Host/Controllers/BridgeController.cs index 88d445cebcc..1f53b43ec20 100644 --- a/src/Tgstation.Server.Host/Controllers/BridgeController.cs +++ b/src/Tgstation.Server.Host/Controllers/BridgeController.cs @@ -74,9 +74,9 @@ public BridgeController(IBridgeDispatcher bridgeDispatcher, IHostApplicationLife ///
/// JSON encoded . /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. [HttpGet] - public async Task Process([FromQuery] string data, CancellationToken cancellationToken) + public async ValueTask Process([FromQuery] string data, CancellationToken cancellationToken) { // Nothing to see here var remoteIP = Request.HttpContext.Connection.RemoteIpAddress; diff --git a/src/Tgstation.Server.Host/Controllers/ByondController.cs b/src/Tgstation.Server.Host/Controllers/ByondController.cs index 92c9878d7b5..156ff784e93 100644 --- a/src/Tgstation.Server.Host/Controllers/ByondController.cs +++ b/src/Tgstation.Server.Host/Controllers/ByondController.cs @@ -74,14 +74,14 @@ public ByondController( /// /// Gets the active . /// - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Retrieved version information successfully. [HttpGet] [TgsAuthorize(ByondRights.ReadActive)] [ProducesResponseType(typeof(ByondResponse), 200)] - public Task Read() + public ValueTask Read() => WithComponentInstance(instance => - Task.FromResult( + ValueTask.FromResult( Json(new ByondResponse { Version = instance.ByondManager.ActiveVersion, @@ -93,15 +93,15 @@ public Task Read() /// The current page. /// The page size. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Retrieved version information successfully. [HttpGet(Routes.List)] [TgsAuthorize(ByondRights.ListInstalled)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => WithComponentInstance( instance => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( instance .ByondManager @@ -122,7 +122,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize ///
/// The containing the to switch to. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Switched active version successfully. /// Created to install and switch active version successfully. [HttpPost] @@ -130,7 +130,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize [ProducesResponseType(typeof(ByondInstallResponse), 200)] [ProducesResponseType(typeof(ByondInstallResponse), 202)] #pragma warning disable CA1506 // TODO: Decomplexify - public async Task Update([FromBody] ByondVersionRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] ByondVersionRequest model, CancellationToken cancellationToken) #pragma warning restore CA1506 { ArgumentNullException.ThrowIfNull(model); @@ -257,7 +257,7 @@ await core.ByondManager.ChangeVersion( ///
/// The containing the to delete. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Created to delete target version successfully. /// Attempted to delete the active BYOND . /// The specified was not installed. @@ -266,7 +266,7 @@ await core.ByondManager.ChangeVersion( [ProducesResponseType(typeof(JobResponse), 202)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Delete([FromBody] ByondVersionDeleteRequest model, CancellationToken cancellationToken) + public async ValueTask Delete([FromBody] ByondVersionDeleteRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -282,12 +282,12 @@ public async Task Delete([FromBody] ByondVersionDeleteRequest mod var byondManager = instance.ByondManager; if (version == byondManager.ActiveVersion) - return Task.FromResult( + return ValueTask.FromResult( Conflict(new ErrorMessageResponse(ErrorCode.ByondCannotDeleteActiveVersion))); var versionNotInstalled = !byondManager.InstalledVersions.Any(x => x == version); - return Task.FromResult( + return ValueTask.FromResult( versionNotInstalled ? this.Gone() : null); diff --git a/src/Tgstation.Server.Host/Controllers/ChatController.cs b/src/Tgstation.Server.Host/Controllers/ChatController.cs index 8b8004cb69a..c1365b1f842 100644 --- a/src/Tgstation.Server.Host/Controllers/ChatController.cs +++ b/src/Tgstation.Server.Host/Controllers/ChatController.cs @@ -99,12 +99,12 @@ static Models.ChatChannel ConvertApiChatChannel(Api.Models.ChatChannel api, Chat ///
/// The . /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Created successfully. [HttpPut] [TgsAuthorize(ChatBotRights.Create)] [ProducesResponseType(typeof(ChatBotResponse), 201)] - public async Task Create([FromBody] ChatBotCreateRequest model, CancellationToken cancellationToken) + public async ValueTask Create([FromBody] ChatBotCreateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -173,12 +173,12 @@ public async Task Create([FromBody] ChatBotCreateRequest model, C ///
/// The to delete. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Chat bot deleted or does not exist. [HttpDelete("{id}")] [TgsAuthorize(ChatBotRights.Delete)] [ProducesResponseType(204)] - public async Task Delete(long id, CancellationToken cancellationToken) + public async ValueTask Delete(long id, CancellationToken cancellationToken) => await WithComponentInstance( async instance => { @@ -200,16 +200,16 @@ await Task.WhenAll( /// The current page. /// The page size. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Listed chat bots successfully. [HttpGet(Routes.List)] [TgsAuthorize(ChatBotRights.Read)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) { var connectionStrings = (AuthenticationContext.GetRight(RightsType.ChatBots) & (ulong)ChatBotRights.ReadConnectionString) != 0; return Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( DatabaseContext .ChatBots @@ -222,7 +222,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize if (!connectionStrings) chatBot.ConnectionString = null; - return Task.CompletedTask; + return ValueTask.CompletedTask; }, page, pageSize, @@ -234,14 +234,14 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize ///
/// The to retrieve. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Retrieved successfully. /// The with the given ID does not exist in this instance. [HttpGet("{id}")] [TgsAuthorize(ChatBotRights.Read)] [ProducesResponseType(typeof(ChatBotResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { var query = DatabaseContext.ChatBots .AsQueryable() @@ -265,7 +265,7 @@ public async Task GetId(long id, CancellationToken cancellationTo ///
/// The . /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Update applied successfully. /// Update applied successfully. not returned based on user permissions. /// The with the given ID does not exist in this instance. @@ -275,7 +275,7 @@ public async Task GetId(long id, CancellationToken cancellationTo [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1502, CA1506 // TODO: Decomplexify - public async Task Update([FromBody] ChatBotUpdateRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] ChatBotUpdateRequest model, CancellationToken cancellationToken) #pragma warning restore CA1502, CA1506 { ArgumentNullException.ThrowIfNull(model); diff --git a/src/Tgstation.Server.Host/Controllers/ComponentInterfacingController.cs b/src/Tgstation.Server.Host/Controllers/ComponentInterfacingController.cs index bab9ae1e62a..45e3829bbb2 100644 --- a/src/Tgstation.Server.Host/Controllers/ComponentInterfacingController.cs +++ b/src/Tgstation.Server.Host/Controllers/ComponentInterfacingController.cs @@ -60,7 +60,7 @@ protected ComponentInterfacingController( } /// - protected override async Task ValidateRequest(CancellationToken cancellationToken) + protected override async ValueTask ValidateRequest(CancellationToken cancellationToken) { if (!useInstanceRequestHeader) return null; @@ -113,11 +113,11 @@ protected bool ValidateInstanceOnlineStatus(Api.Models.Instance metadata) /// /// Run a given with the relevant . /// - /// A accepting the and returning a with the . + /// A accepting the and returning a with the . /// The to grab. If , will be used. - /// A resulting in the that should be returned. + /// A resulting in the that should be returned. /// The context of should be as small as possible so as to avoid race conditions. This function can return a if the requested instance was offline. - protected async Task WithComponentInstance(Func> action, Models.Instance instance = null) + protected async ValueTask WithComponentInstance(Func> action, Models.Instance instance = null) { ArgumentNullException.ThrowIfNull(action); diff --git a/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs b/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs index 6be4c6df5fe..b71703af41f 100644 --- a/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs +++ b/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs @@ -58,14 +58,14 @@ public ConfigurationController( ///
/// The representing the file. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// File updated successfully. /// File upload ticket created successfully. [HttpPost] [TgsAuthorize(ConfigurationRights.Write)] [ProducesResponseType(typeof(ConfigurationFileResponse), 200)] [ProducesResponseType(typeof(ConfigurationFileResponse), 202)] - public async Task Update([FromBody] ConfigurationFileRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] ConfigurationFileRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); if (ForbidDueToModeConflicts(model.Path, out var systemIdentity)) @@ -109,7 +109,7 @@ public async Task Update([FromBody] ConfigurationFileRequest mode /// /// The path of the file to get. /// The for the operation. - /// A resulting in the for the operation.> + /// A resulting in the for the operation.> /// File read successfully.> /// File does not currently exist. [HttpGet(Routes.File + "/{*filePath}")] @@ -117,7 +117,7 @@ public async Task Update([FromBody] ConfigurationFileRequest mode [ProducesResponseType(typeof(ConfigurationFileResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task File(string filePath, CancellationToken cancellationToken) + public async ValueTask File(string filePath, CancellationToken cancellationToken) { if (ForbidDueToModeConflicts(filePath, out var systemIdentity)) return Forbid(); @@ -158,7 +158,7 @@ public async Task File(string filePath, CancellationToken cancell /// The current page. /// The page size. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Directory listed successfully.> /// Directory does not currently exist. [HttpGet(Routes.List + "/{*directoryPath}")] @@ -166,7 +166,7 @@ public async Task File(string filePath, CancellationToken cancell [ProducesResponseType(typeof(PaginatedResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public Task Directory( + public ValueTask Directory( string directoryPath, [FromQuery] int? page, [FromQuery] int? pageSize, @@ -222,11 +222,11 @@ public Task Directory( /// The current page. /// The page size. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. [HttpGet(Routes.List)] [TgsAuthorize(ConfigurationRights.List)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List( + public ValueTask List( [FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Directory(null, page, pageSize, cancellationToken); @@ -236,7 +236,7 @@ public Task List( /// /// The representing the directory. /// The for the operation. - /// A resulting in the for the operation. + /// A resulting in the for the operation. /// Directory already exists. /// Directory created successfully. [HttpPut] @@ -244,7 +244,7 @@ public Task List( [ProducesResponseType(typeof(ConfigurationFileResponse), 200)] [ProducesResponseType(typeof(ConfigurationFileResponse), 201)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] - public async Task CreateDirectory([FromBody] ConfigurationFileRequest model, CancellationToken cancellationToken) + public async ValueTask CreateDirectory([FromBody] ConfigurationFileRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -297,13 +297,13 @@ public async Task CreateDirectory([FromBody] ConfigurationFileReq /// /// A representing the path to the directory to delete. /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Empty directory deleted successfully. [HttpDelete] [TgsAuthorize(ConfigurationRights.Delete)] [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] - public async Task DeleteDirectory([FromBody] ConfigurationFileRequest directory, CancellationToken cancellationToken) + public async ValueTask DeleteDirectory([FromBody] ConfigurationFileRequest directory, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(directory); diff --git a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs index 10d179792c8..f4613f81d00 100644 --- a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs +++ b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs @@ -73,12 +73,12 @@ public DreamDaemonController( /// Launches the watchdog. /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Watchdog launch started successfully. [HttpPut] [TgsAuthorize(DreamDaemonRights.Start)] [ProducesResponseType(typeof(JobResponse), 202)] - public Task Create(CancellationToken cancellationToken) + public ValueTask Create(CancellationToken cancellationToken) => WithComponentInstance(async instance => { if (instance.Watchdog.Status != WatchdogStatus.Offline) @@ -103,25 +103,25 @@ await jobManager.RegisterOperation( /// Get the watchdog status. /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Read information successfully. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. [HttpGet] [TgsAuthorize(DreamDaemonRights.ReadMetadata | DreamDaemonRights.ReadRevision)] [ProducesResponseType(typeof(DreamDaemonResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public Task Read(CancellationToken cancellationToken) => ReadImpl(null, cancellationToken); + public ValueTask Read(CancellationToken cancellationToken) => ReadImpl(null, cancellationToken); /// /// Stops the Watchdog if it's running. /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Watchdog terminated. [HttpDelete] [TgsAuthorize(DreamDaemonRights.Shutdown)] [ProducesResponseType(204)] - public Task Delete(CancellationToken cancellationToken) + public ValueTask Delete(CancellationToken cancellationToken) => WithComponentInstance(async instance => { await instance.Watchdog.Terminate(false, cancellationToken); @@ -133,7 +133,7 @@ public Task Delete(CancellationToken cancellationToken) /// /// The with updated settings. /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Settings applied successfully. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. [HttpPost] @@ -157,7 +157,7 @@ public Task Delete(CancellationToken cancellationToken) [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1502 // TODO: Decomplexify #pragma warning disable CA1506 - public async Task Update([FromBody] DreamDaemonRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] DreamDaemonRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -259,12 +259,12 @@ bool CheckModified(Expression to restart the Watchdog. It will not start if it wasn't already running. /// /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Restart started successfully. [HttpPatch] [TgsAuthorize(DreamDaemonRights.Restart)] [ProducesResponseType(typeof(JobResponse), 202)] - public Task Restart(CancellationToken cancellationToken) + public ValueTask Restart(CancellationToken cancellationToken) => WithComponentInstance(async instance => { var job = new Job @@ -292,12 +292,12 @@ await jobManager.RegisterOperation( /// Creates a to generate a DreamDaemon process dump. /// /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Dump started successfully. [HttpPatch(Routes.Diagnostics)] [TgsAuthorize(DreamDaemonRights.CreateDump)] [ProducesResponseType(typeof(JobResponse), 202)] - public Task CreateDump(CancellationToken cancellationToken) + public ValueTask CreateDump(CancellationToken cancellationToken) => WithComponentInstance(async instance => { var job = new Job @@ -326,8 +326,8 @@ await jobManager.RegisterOperation( /// /// The to operate on if any. /// The for the operation. - /// A resulting in the of the operation. - Task ReadImpl(DreamDaemonSettings settings, CancellationToken cancellationToken) + /// A resulting in the of the operation. + ValueTask ReadImpl(DreamDaemonSettings settings, CancellationToken cancellationToken) => WithComponentInstance(async instance => { var dd = instance.Watchdog; diff --git a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs index d26c23aba26..3c4431a3e1a 100644 --- a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs +++ b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs @@ -69,12 +69,12 @@ public DreamMakerController( /// Read current deployment settings. /// /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Read deployment settings successfully. [HttpGet] [TgsAuthorize(DreamMakerRights.Read)] [ProducesResponseType(typeof(DreamMakerResponse), 200)] - public async Task Read(CancellationToken cancellationToken) + public async ValueTask Read(CancellationToken cancellationToken) { var dreamMakerSettings = await DatabaseContext .DreamMakerSettings @@ -89,14 +89,14 @@ public async Task Read(CancellationToken cancellationToken) /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// retrieved successfully. /// Specified ID does not exist in this instance. [HttpGet("{id}")] [TgsAuthorize(DreamMakerRights.CompileJobs)] [ProducesResponseType(typeof(CompileJobResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 404)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { var compileJob = await BaseCompileJobsQuery() .Where(x => x.Id == id) @@ -112,14 +112,14 @@ public async Task GetId(long id, CancellationToken cancellationTo /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved s successfully. [HttpGet(Routes.List)] [TgsAuthorize(DreamMakerRights.CompileJobs)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( BaseCompileJobsQuery() .OrderByDescending(x => x.Job.StoppedAt))), @@ -132,12 +132,12 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize /// Begin deploying repository code. /// /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Created deployment successfully. [HttpPut] [TgsAuthorize(DreamMakerRights.Compile)] [ProducesResponseType(typeof(JobResponse), 202)] - public async Task Create(CancellationToken cancellationToken) + public async ValueTask Create(CancellationToken cancellationToken) { var job = new Job { @@ -161,7 +161,7 @@ await jobManager.RegisterOperation( /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Changes applied successfully. The updated will be returned. /// Changes applied successfully. The updated will be not be returned due to permissions. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. @@ -175,7 +175,7 @@ await jobManager.RegisterOperation( [ProducesResponseType(typeof(DreamMakerResponse), 200)] [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Update([FromBody] DreamMakerRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] DreamMakerRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); diff --git a/src/Tgstation.Server.Host/Controllers/HomeController.cs b/src/Tgstation.Server.Host/Controllers/HomeController.cs index a7286839a24..a0be005e9e3 100644 --- a/src/Tgstation.Server.Host/Controllers/HomeController.cs +++ b/src/Tgstation.Server.Host/Controllers/HomeController.cs @@ -147,14 +147,14 @@ public HomeController( /// /// The for the operation. /// - /// A resuting in the containing of the if a properly authenticated API request, the web control panel if on a browser and enabled, otherwise. + /// A resuting in the containing of the if a properly authenticated API request, the web control panel if on a browser and enabled, otherwise. /// /// retrieved successfully. [HttpGet] [AllowAnonymous] [ProducesResponseType(typeof(ServerInformationResponse), 200)] #pragma warning disable CA1506 - public async Task Home(CancellationToken cancellationToken) + public async ValueTask Home(CancellationToken cancellationToken) { if (controlPanelConfiguration.Enable) Response.Headers.Add( @@ -211,7 +211,7 @@ public async Task Home(CancellationToken cancellationToken) /// Attempt to authenticate a using . /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// User logged in and generated successfully. /// User authentication failed. /// User authenticated but is disabled by an administrator. @@ -220,7 +220,7 @@ public async Task Home(CancellationToken cancellationToken) [ProducesResponseType(typeof(TokenResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 429)] #pragma warning disable CA1506 // TODO: Decomplexify - public async Task CreateToken(CancellationToken cancellationToken) + public async ValueTask CreateToken(CancellationToken cancellationToken) { if (ApiHeaders == null) { diff --git a/src/Tgstation.Server.Host/Controllers/InstanceController.cs b/src/Tgstation.Server.Host/Controllers/InstanceController.cs index 0b29b869a6c..0e2ebf234e6 100644 --- a/src/Tgstation.Server.Host/Controllers/InstanceController.cs +++ b/src/Tgstation.Server.Host/Controllers/InstanceController.cs @@ -120,14 +120,14 @@ public InstanceController( /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Instance attached successfully. /// Instance created successfully. [HttpPut] [TgsAuthorize(InstanceManagerRights.Create)] [ProducesResponseType(typeof(InstanceResponse), 200)] [ProducesResponseType(typeof(InstanceResponse), 201)] - public async Task Create([FromBody] InstanceCreateRequest model, CancellationToken cancellationToken) + public async ValueTask Create([FromBody] InstanceCreateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -199,7 +199,7 @@ await DatabaseContext .Any(path => InstanceIsChildOf(path)) ?? true)) return BadRequest(new ErrorMessageResponse(ErrorCode.InstanceNotAtWhitelistedPath)); - async Task DirExistsAndIsNotEmpty() + async ValueTask DirExistsAndIsNotEmpty() { if (!await ioManager.DirectoryExists(model.Path, cancellationToken)) return false; @@ -272,14 +272,14 @@ async Task DirExistsAndIsNotEmpty() /// /// The of the instance to detach. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Instance detatched successfully. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. [HttpDelete("{id}")] [TgsAuthorize(InstanceManagerRights.Delete)] [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Delete(long id, CancellationToken cancellationToken) + public async ValueTask Delete(long id, CancellationToken cancellationToken) { var originalModel = await DatabaseContext .Instances @@ -315,7 +315,7 @@ public async Task Delete(long id, CancellationToken cancellationT /// /// The updated settings. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Instance updated successfully. /// Instance updated successfully and relocation job created. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. @@ -325,7 +325,7 @@ public async Task Delete(long id, CancellationToken cancellationT [ProducesResponseType(typeof(InstanceResponse), 202)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1502 // TODO: Decomplexify - public async Task Update([FromBody] InstanceUpdateRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] InstanceUpdateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -512,12 +512,12 @@ await WithComponentInstance( /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved s successfully. [HttpGet(Routes.List)] [TgsAuthorize(InstanceManagerRights.List | InstanceManagerRights.Read)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public async Task List( + public async ValueTask List( [FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) @@ -552,7 +552,7 @@ public async Task List( var needsUpdate = false; var result = await Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( GetBaseQuery() .OrderBy(x => x.Id))), @@ -577,14 +577,14 @@ public async Task List( /// /// The instance to retrieve. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved successfully. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. [HttpGet("{id}")] [TgsAuthorize(InstanceManagerRights.List | InstanceManagerRights.Read)] [ProducesResponseType(typeof(InstanceResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { var cantList = !AuthenticationContext.PermissionSet.InstanceManagerRights.Value.HasFlag(InstanceManagerRights.List); IQueryable QueryForUser() @@ -634,13 +634,13 @@ public async Task GetId(long id, CancellationToken cancellationTo /// /// The instance to give permissions on. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Granted permissions successfully. [HttpPatch("{id}")] [TgsAuthorize(InstanceManagerRights.GrantPermissions)] [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task GrantPermissions(long id, CancellationToken cancellationToken) + public async ValueTask GrantPermissions(long id, CancellationToken cancellationToken) { IQueryable BaseQuery() => DatabaseContext .Instances @@ -678,8 +678,8 @@ public async Task GrantPermissions(long id, CancellationToken can /// /// The . /// The for the operation. - /// A resulting in the new or if ports could not be allocated. - async Task CreateDefaultInstance(InstanceCreateRequest initialSettings, CancellationToken cancellationToken) + /// A resulting in the new or if ports could not be allocated. + async ValueTask CreateDefaultInstance(InstanceCreateRequest initialSettings, CancellationToken cancellationToken) { var ddPort = await portAllocator.GetAvailablePort(1024, false, cancellationToken); if (!ddPort.HasValue) @@ -797,8 +797,8 @@ string NormalizePath(string path) /// /// The to populate. /// The for the operation. - /// A representing the running operation. - async Task CheckAccessible(InstanceResponse instanceResponse, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask CheckAccessible(InstanceResponse instanceResponse, CancellationToken cancellationToken) { instanceResponse.Accessible = await DatabaseContext .InstancePermissionSets diff --git a/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs b/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs index e0be1eb3b16..ca8fdae67bb 100644 --- a/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs +++ b/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs @@ -53,7 +53,7 @@ public InstancePermissionSetController( /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// created successfully. /// The does not exist. [HttpPut] @@ -61,7 +61,7 @@ public InstancePermissionSetController( [ProducesResponseType(typeof(InstancePermissionSetResponse), 201)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1506 - public async Task Create([FromBody] InstancePermissionSetRequest model, CancellationToken cancellationToken) + public async ValueTask Create([FromBody] InstancePermissionSetRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -116,7 +116,7 @@ public async Task Create([FromBody] InstancePermissionSetRequest /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// updated successfully. /// The requested does not currently exist. [HttpPost] @@ -124,7 +124,7 @@ public async Task Create([FromBody] InstancePermissionSetRequest [ProducesResponseType(typeof(InstancePermissionSetResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1506 // TODO: Decomplexify - public async Task Update([FromBody] InstancePermissionSetRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] InstancePermissionSetRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -174,14 +174,14 @@ public async Task Update([FromBody] InstancePermissionSetRequest /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved s successfully. [HttpGet(Routes.List)] [TgsAuthorize(InstancePermissionSetRights.Read)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( DatabaseContext .Instances @@ -199,14 +199,14 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieve successfully. /// The requested does not currently exist. [HttpGet("{id}")] [TgsAuthorize(InstancePermissionSetRights.Read)] [ProducesResponseType(typeof(InstancePermissionSetResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { // this functions as userId var permissionSet = await DatabaseContext @@ -226,14 +226,14 @@ public async Task GetId(long id, CancellationToken cancellationTo /// /// The to delete. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Target deleted. /// Target or no longer exists. [HttpDelete("{id}")] [TgsAuthorize(InstancePermissionSetRights.Write)] [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Delete(long id, CancellationToken cancellationToken) + public async ValueTask Delete(long id, CancellationToken cancellationToken) { var numDeleted = await DatabaseContext .Instances diff --git a/src/Tgstation.Server.Host/Controllers/JobController.cs b/src/Tgstation.Server.Host/Controllers/JobController.cs index 77f1221b516..84f4cc50845 100644 --- a/src/Tgstation.Server.Host/Controllers/JobController.cs +++ b/src/Tgstation.Server.Host/Controllers/JobController.cs @@ -59,14 +59,14 @@ public JobController( /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved active s successfully. [HttpGet] [TgsAuthorize] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task Read([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask Read([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( DatabaseContext .Jobs @@ -86,14 +86,14 @@ public Task Read([FromQuery] int? page, [FromQuery] int? pageSize /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved s successfully. [HttpGet(Routes.List)] [TgsAuthorize] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( DatabaseContext .Jobs @@ -112,7 +112,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize /// /// The of the to cancel. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// cancellation requested successfully. /// does not exist in this instance. /// could not be found in the job manager. Has it already completed?. @@ -120,7 +120,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize [TgsAuthorize] [ProducesResponseType(typeof(JobResponse), 202)] [ProducesResponseType(typeof(ErrorMessageResponse), 404)] - public async Task Delete(long id, CancellationToken cancellationToken) + public async ValueTask Delete(long id, CancellationToken cancellationToken) { // don't care if an instance post or not at this point var job = await DatabaseContext @@ -147,14 +147,14 @@ public async Task Delete(long id, CancellationToken cancellationT /// /// The of the to retrieve. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved successfully. /// does not exist in this instance. [HttpGet("{id}")] [TgsAuthorize] [ProducesResponseType(typeof(JobResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 404)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { var job = await DatabaseContext .Jobs @@ -174,11 +174,11 @@ public async Task GetId(long id, CancellationToken cancellationTo /// Supplements s with their . /// /// The to augment. - /// A representing the running operation. - Task AddJobProgressResponseTransformer(JobResponse jobResponse) + /// A representing the running operation. + ValueTask AddJobProgressResponseTransformer(JobResponse jobResponse) { jobManager.SetJobProgress(jobResponse); - return Task.CompletedTask; + return ValueTask.CompletedTask; } } } diff --git a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs index 6b877c054b0..0b02d7d0c15 100644 --- a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs +++ b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs @@ -73,14 +73,14 @@ public RepositoryController( /// /// The . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// The repository was created successfully and the to clone it has begun. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. [HttpPut] [TgsAuthorize(RepositoryRights.SetOrigin)] [ProducesResponseType(typeof(RepositoryResponse), 201)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Create([FromBody] RepositoryCreateRequest model, CancellationToken cancellationToken) + public async ValueTask Create([FromBody] RepositoryCreateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -193,14 +193,14 @@ await databaseContextFactory.UseContext( /// Delete the repository. /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Job to delete the repository created successfully. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. [HttpDelete] [TgsAuthorize(RepositoryRights.Delete)] [ProducesResponseType(typeof(RepositoryResponse), 202)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Delete(CancellationToken cancellationToken) + public async ValueTask Delete(CancellationToken cancellationToken) { var currentModel = await DatabaseContext .RepositorySettings @@ -237,7 +237,7 @@ await jobManager.RegisterOperation( /// Get the repository's status. /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Retrieved the repository settings successfully. /// Retrieved the repository settings successfully, though they did not previously exist. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. @@ -246,7 +246,7 @@ await jobManager.RegisterOperation( [ProducesResponseType(typeof(RepositoryResponse), 200)] [ProducesResponseType(typeof(RepositoryResponse), 201)] [ProducesResponseType(typeof(RepositoryResponse), 410)] - public async Task Read(CancellationToken cancellationToken) + public async ValueTask Read(CancellationToken cancellationToken) { var currentModel = await DatabaseContext .RepositorySettings @@ -287,7 +287,7 @@ public async Task Read(CancellationToken cancellationToken) /// /// The . /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Updated the repository settings successfully. /// Updated the repository settings successfully and a was created to make the requested git changes. /// The database entity for the requested instance could not be retrieved. The instance was likely detached. @@ -306,7 +306,7 @@ public async Task Read(CancellationToken cancellationToken) [ProducesResponseType(typeof(RepositoryResponse), 202)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1502 // TODO: Decomplexify - public async Task Update([FromBody] RepositoryUpdateRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] RepositoryUpdateRequest model, CancellationToken cancellationToken) #pragma warning restore CA1502 { ArgumentNullException.ThrowIfNull(model); @@ -484,8 +484,8 @@ await jobManager.RegisterOperation( /// The active . /// The active . /// The for the operation. - /// A resulting in if the was modified in a way that requires saving, otherwise. - async Task PopulateApi( + /// A resulting in if the was modified in a way that requires saving, otherwise. + async ValueTask PopulateApi( RepositoryResponse apiResponse, IRepository repository, IDatabaseContext databaseContext, diff --git a/src/Tgstation.Server.Host/Controllers/SwarmController.cs b/src/Tgstation.Server.Host/Controllers/SwarmController.cs index a94599c9207..8b941d425c9 100644 --- a/src/Tgstation.Server.Host/Controllers/SwarmController.cs +++ b/src/Tgstation.Server.Host/Controllers/SwarmController.cs @@ -89,7 +89,7 @@ public SwarmController( /// The for the operation. /// The of the operation. [HttpPost(SwarmConstants.RegisterRoute)] - public async Task Register([FromBody] SwarmRegistrationRequest registrationRequest, CancellationToken cancellationToken) + public async ValueTask Register([FromBody] SwarmRegistrationRequest registrationRequest, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(registrationRequest); @@ -108,7 +108,7 @@ public async Task Register([FromBody] SwarmRegistrationRequest re /// The for the operation. /// A resulting in the of the operation. [HttpDelete(SwarmConstants.RegisterRoute)] - public async Task UnregisterNode(CancellationToken cancellationToken) + public async ValueTask UnregisterNode(CancellationToken cancellationToken) { if (!ValidateRegistration()) return Forbid(); @@ -138,7 +138,7 @@ public IActionResult HealthCheck() /// A resulting in the of the operation. [HttpGet(SwarmConstants.UpdateRoute)] [Produces(MediaTypeNames.Application.Octet)] - public Task GetUpdatePackage([FromQuery] string ticket, CancellationToken cancellationToken) + public ValueTask GetUpdatePackage([FromQuery] string ticket, CancellationToken cancellationToken) => transferService.GenerateDownloadResponse(this, ticket, cancellationToken); /// @@ -163,9 +163,9 @@ public IActionResult UpdateNodeList([FromBody] SwarmServersUpdateRequest servers /// /// The . /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. [HttpPut(SwarmConstants.UpdateRoute)] - public async Task PrepareUpdate([FromBody] SwarmUpdateRequest updateRequest, CancellationToken cancellationToken) + public async ValueTask PrepareUpdate([FromBody] SwarmUpdateRequest updateRequest, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(updateRequest); @@ -183,9 +183,9 @@ public async Task PrepareUpdate([FromBody] SwarmUpdateRequest upd /// Update commit endpoint. /// /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. [HttpPost(SwarmConstants.UpdateRoute)] - public async Task CommitUpdate(CancellationToken cancellationToken) + public async ValueTask CommitUpdate(CancellationToken cancellationToken) { if (!ValidateRegistration()) return Forbid(); @@ -199,9 +199,9 @@ public async Task CommitUpdate(CancellationToken cancellationToke /// /// Update abort endpoint. /// - /// A resulting in the of the operation. + /// A resulting in the of the operation. [HttpDelete(SwarmConstants.UpdateRoute)] - public async Task AbortUpdate() + public async ValueTask AbortUpdate() { if (!ValidateRegistration()) return Forbid(); diff --git a/src/Tgstation.Server.Host/Controllers/TransferController.cs b/src/Tgstation.Server.Host/Controllers/TransferController.cs index 6374b65557c..be12cfda911 100644 --- a/src/Tgstation.Server.Host/Controllers/TransferController.cs +++ b/src/Tgstation.Server.Host/Controllers/TransferController.cs @@ -54,14 +54,14 @@ public TransferController( /// /// The for the download. /// The for the operation. - /// A resulting in the of the method. + /// A resulting in the of the method. /// Started streaming download successfully. /// The was no longer or was never valid. [TgsAuthorize] [HttpGet] [ProducesResponseType(200, Type = typeof(LimitedStreamResult))] [ProducesResponseType(410, Type = typeof(ErrorMessageResponse))] - public Task Download([Required, FromQuery] string ticket, CancellationToken cancellationToken) + public ValueTask Download([Required, FromQuery] string ticket, CancellationToken cancellationToken) => fileTransferService.GenerateDownloadResponse(this, ticket, cancellationToken); /// @@ -69,7 +69,7 @@ public Task Download([Required, FromQuery] string ticket, Cancell /// /// The for the upload. /// The for the operation. - /// A resulting in the of the method. + /// A resulting in the of the method. /// Uploaded file successfully. /// An error occurred during the upload. /// The was no longer or was never valid. @@ -77,7 +77,7 @@ public Task Download([Required, FromQuery] string ticket, Cancell [HttpPut] [ProducesResponseType(204)] [ProducesResponseType(410, Type = typeof(ErrorMessageResponse))] - public async Task Upload([Required, FromQuery] string ticket, CancellationToken cancellationToken) + public async ValueTask Upload([Required, FromQuery] string ticket, CancellationToken cancellationToken) { if (ticket == null) return BadRequest(new ErrorMessageResponse(ErrorCode.ModelValidationFailure)); diff --git a/src/Tgstation.Server.Host/Controllers/UserController.cs b/src/Tgstation.Server.Host/Controllers/UserController.cs index b50e424c938..04559bde3c4 100644 --- a/src/Tgstation.Server.Host/Controllers/UserController.cs +++ b/src/Tgstation.Server.Host/Controllers/UserController.cs @@ -75,14 +75,14 @@ public UserController( /// /// The . /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// created successfully. /// The requested system identifier could not be found. [HttpPut] [TgsAuthorize(AdministrationRights.WriteUsers)] [ProducesResponseType(typeof(UserResponse), 201)] #pragma warning disable CA1502, CA1506 - public async Task Create([FromBody] UserCreateRequest model, CancellationToken cancellationToken) + public async ValueTask Create([FromBody] UserCreateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -155,7 +155,7 @@ public async Task Create([FromBody] UserCreateRequest model, Canc /// /// The to update. /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// updated successfully. /// updated successfully. Not returned due to lack of permissions. /// Requested does not exist. @@ -168,7 +168,7 @@ public async Task Create([FromBody] UserCreateRequest model, Canc [ProducesResponseType(typeof(ErrorMessageResponse), 410)] #pragma warning disable CA1502 // TODO: Decomplexify #pragma warning disable CA1506 - public async Task Update([FromBody] UserUpdateRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] UserUpdateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -336,14 +336,14 @@ public async Task Update([FromBody] UserUpdateRequest model, Canc /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// Retrieved s successfully. [HttpGet(Routes.List)] [TgsAuthorize(AdministrationRights.ReadUsers)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( DatabaseContext .Users @@ -365,14 +365,14 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize /// /// The to retrieve. /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// The was retrieved successfully. /// The does not exist. [HttpGet("{id}")] [TgsAuthorize] [ProducesResponseType(typeof(UserResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 404)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { if (id == AuthenticationContext.User.Id) return Read(); @@ -403,8 +403,8 @@ public async Task GetId(long id, CancellationToken cancellationTo /// /// The to use as a template. /// The for the operation. - /// A resulting in a new on success, if the requested did not exist. - async Task CreateNewUserFromModel(Api.Models.Internal.UserApiBase model, CancellationToken cancellationToken) + /// A resulting in a new on success, if the requested did not exist. + async ValueTask CreateNewUserFromModel(Api.Models.Internal.UserApiBase model, CancellationToken cancellationToken) { Models.PermissionSet permissionSet = null; UserGroup group = null; diff --git a/src/Tgstation.Server.Host/Controllers/UserGroupController.cs b/src/Tgstation.Server.Host/Controllers/UserGroupController.cs index 7b794d86e59..14269e3254f 100644 --- a/src/Tgstation.Server.Host/Controllers/UserGroupController.cs +++ b/src/Tgstation.Server.Host/Controllers/UserGroupController.cs @@ -60,12 +60,12 @@ public UserGroupController( /// /// The . /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// created successfully. [HttpPut] [TgsAuthorize(AdministrationRights.WriteUsers)] [ProducesResponseType(typeof(UserGroupResponse), 201)] - public async Task Create([FromBody] UserGroupCreateRequest model, CancellationToken cancellationToken) + public async ValueTask Create([FromBody] UserGroupCreateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -103,13 +103,13 @@ public async Task Create([FromBody] UserGroupCreateRequest model, /// /// The . /// The for the operation. - /// A resulting in the of the operation. + /// A resulting in the of the operation. /// updated successfully. /// The requested does not currently exist. [HttpPost] [TgsAuthorize(AdministrationRights.WriteUsers)] [ProducesResponseType(typeof(UserGroupResponse), 200)] - public async Task Update([FromBody] UserGroupUpdateRequest model, CancellationToken cancellationToken) + public async ValueTask Update([FromBody] UserGroupUpdateRequest model, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(model); @@ -148,14 +148,14 @@ public async Task Update([FromBody] UserGroupUpdateRequest model, /// /// The of the . /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieve successfully. /// The requested does not currently exist. [HttpGet("{id}")] [TgsAuthorize(AdministrationRights.ReadUsers)] [ProducesResponseType(typeof(UserGroupResponse), 200)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task GetId(long id, CancellationToken cancellationToken) + public async ValueTask GetId(long id, CancellationToken cancellationToken) { // this functions as userId var group = await DatabaseContext @@ -176,14 +176,14 @@ public async Task GetId(long id, CancellationToken cancellationTo /// The current page. /// The page size. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// Retrieved s successfully. [HttpGet(Routes.List)] [TgsAuthorize(AdministrationRights.ReadUsers)] [ProducesResponseType(typeof(PaginatedResponse), 200)] - public Task List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) + public ValueTask List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken) => Paginated( - () => Task.FromResult( + () => ValueTask.FromResult( new PaginatableResult( DatabaseContext .Groups @@ -201,7 +201,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize /// /// The of the to delete. /// The for the operation. - /// A resulting in the of the request. + /// A resulting in the of the request. /// was deleted. /// The is not empty. /// The didn't exist. @@ -210,7 +210,7 @@ public Task List([FromQuery] int? page, [FromQuery] int? pageSize [ProducesResponseType(204)] [ProducesResponseType(typeof(ErrorMessageResponse), 409)] [ProducesResponseType(typeof(ErrorMessageResponse), 410)] - public async Task Delete(long id, CancellationToken cancellationToken) + public async ValueTask Delete(long id, CancellationToken cancellationToken) { var numDeleted = await DatabaseContext .Groups diff --git a/src/Tgstation.Server.Host/Extensions/FileTransferStreamHandlerExtensions.cs b/src/Tgstation.Server.Host/Extensions/FileTransferStreamHandlerExtensions.cs index 83cd739213a..8028f8ab8db 100644 --- a/src/Tgstation.Server.Host/Extensions/FileTransferStreamHandlerExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/FileTransferStreamHandlerExtensions.cs @@ -28,8 +28,8 @@ static class FileTransferStreamHandlerExtensions /// The the request is coming from. /// The for the download. /// The for the operation. - /// A resulting in the of the method. - public static async Task GenerateDownloadResponse( + /// A resulting in the of the method. + public static async ValueTask GenerateDownloadResponse( this IFileTransferStreamHandler fileTransferService, ControllerBase controller, string ticket, diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/SwarmRpcMapper.cs b/tests/Tgstation.Server.Host.Tests/Swarm/SwarmRpcMapper.cs index d019ce54f58..167c058c19d 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/SwarmRpcMapper.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/SwarmRpcMapper.cs @@ -184,12 +184,21 @@ async Task MapRequest( if (controllerMethod.ReturnType != typeof(IActionResult)) { - Assert.AreEqual(typeof(Task), controllerMethod.ReturnType); + var isValueTask = controllerMethod.ReturnType == typeof(ValueTask); + if (!isValueTask) + Assert.AreEqual(typeof(Task), controllerMethod.ReturnType); + var lastParam = controllerMethod.GetParameters().LastOrDefault(); if (lastParam?.ParameterType == typeof(CancellationToken)) args.Add(cancellationToken); - var invocationTask = (Task)controllerMethod.Invoke(controller, args.ToArray()); + var rawTask = controllerMethod.Invoke(controller, args.ToArray()); + Task invocationTask; + if (isValueTask) + invocationTask = ((ValueTask)rawTask).AsTask(); + else + invocationTask = (Task)rawTask; + result = await invocationTask; } else diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs index 0c780e04f4c..0021948045c 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs @@ -270,18 +270,18 @@ private async Task ShutdownService(CancellationToken cancellationToken) return result; } - Task BeginUpdate(ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) + ValueTask BeginUpdate(ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) { logger.LogTrace("BeginUpdate..."); if (UpdateTask?.IsCompleted == false) - return Task.FromResult(ServerUpdateResult.UpdateInProgress); + return ValueTask.FromResult(ServerUpdateResult.UpdateInProgress); if (UpdateResult == ServerUpdateResult.Started) { UpdateTask = ExecuteUpdate(fileStreamProvider, version, cancellationToken, CriticalCancellationTokenSource.Token); } - return Task.FromResult(UpdateResult); + return ValueTask.FromResult(UpdateResult); } async Task ExecuteUpdate(IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken, CancellationToken criticalCancellationToken) From cc6ee6673322347101502468d03d309057250e16 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 16:05:48 -0400 Subject: [PATCH 21/33] ValueTask conversion for high level server stuff --- .../Components/IInstanceFactory.cs | 4 +-- .../Components/InstanceFactory.cs | 2 +- .../Core/IServerControl.cs | 10 +++--- .../Core/IServerUpdateExecutor.cs | 4 +-- .../Core/IServerUpdateInitiator.cs | 4 +-- .../Core/IServerUpdater.cs | 4 +-- .../Core/ServerUpdateInitiator.cs | 2 +- .../Core/ServerUpdater.cs | 16 ++++----- src/Tgstation.Server.Host/IServer.cs | 4 +-- src/Tgstation.Server.Host/IServerFactory.cs | 4 +-- src/Tgstation.Server.Host/Program.cs | 6 ++-- src/Tgstation.Server.Host/Server.cs | 14 ++++---- src/Tgstation.Server.Host/ServerFactory.cs | 2 +- .../Program.cs | 2 +- .../Core/TestServerUpdateInitiator.cs | 2 +- .../TestProgram.cs | 6 ++-- .../TestServerFactory.cs | 6 ++-- .../Live/LiveTestingServer.cs | 4 +-- .../Live/TestLiveServer.cs | 36 +++++++++---------- 19 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/IInstanceFactory.cs b/src/Tgstation.Server.Host/Components/IInstanceFactory.cs index fda8c9afad2..6258614b5f5 100644 --- a/src/Tgstation.Server.Host/Components/IInstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/IInstanceFactory.cs @@ -15,8 +15,8 @@ interface IInstanceFactory : IComponentService /// /// The to use. /// The . - /// A resulting in a new . - Task CreateInstance(IBridgeRegistrar bridgeRegistrar, Models.Instance metadata); + /// A resulting in a new . + ValueTask CreateInstance(IBridgeRegistrar bridgeRegistrar, Models.Instance metadata); /// /// Create an that resolves to the "Game" directory of the defined by . diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index 221b5f28220..9667a9f6e80 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -257,7 +257,7 @@ public IIOManager CreateGameIOManager(Models.Instance metadata) /// #pragma warning disable CA1506 // TODO: Decomplexify - public async Task CreateInstance(IBridgeRegistrar bridgeRegistrar, Models.Instance metadata) + public async ValueTask CreateInstance(IBridgeRegistrar bridgeRegistrar, Models.Instance metadata) { ArgumentNullException.ThrowIfNull(bridgeRegistrar); ArgumentNullException.ThrowIfNull(metadata); diff --git a/src/Tgstation.Server.Host/Core/IServerControl.cs b/src/Tgstation.Server.Host/Core/IServerControl.cs index bc081b3201d..d864080db69 100644 --- a/src/Tgstation.Server.Host/Core/IServerControl.cs +++ b/src/Tgstation.Server.Host/Core/IServerControl.cs @@ -36,21 +36,21 @@ public interface IServerControl /// /// Restarts the . /// - /// A representing the running operation. - Task Restart(); + /// A representing the running operation. + ValueTask Restart(); /// /// Gracefully shutsdown the . /// /// If the graceful shutdown should detach any running watchdog. If the server will wait for the next TgsReboot() or world exit before shutting down. - /// A representing the running operation. - Task GracefulShutdown(bool detach); + /// A representing the running operation. + ValueTask GracefulShutdown(bool detach); /// /// Kill the server with a fatal exception. /// /// The to propagate to the watchdog if any. /// A representing the running operation. - Task Die(Exception exception); + ValueTask Die(Exception exception); } } diff --git a/src/Tgstation.Server.Host/Core/IServerUpdateExecutor.cs b/src/Tgstation.Server.Host/Core/IServerUpdateExecutor.cs index c1bf92405a4..c2bf6f2090c 100644 --- a/src/Tgstation.Server.Host/Core/IServerUpdateExecutor.cs +++ b/src/Tgstation.Server.Host/Core/IServerUpdateExecutor.cs @@ -14,7 +14,7 @@ public interface IServerUpdateExecutor /// The path to extract the update zip to. /// The for non-critical parts of this operation. /// The for the operation. Must not be trivial as it can desync swarm nodes if fired at an inappropriate time. - /// A resulting in if the update was successful, otherwise. - Task ExecuteUpdate(string updatePath, CancellationToken cancellationToken, CancellationToken criticalCancellationToken); + /// A resulting in if the update was successful, otherwise. + ValueTask ExecuteUpdate(string updatePath, CancellationToken cancellationToken, CancellationToken criticalCancellationToken); } } diff --git a/src/Tgstation.Server.Host/Core/IServerUpdateInitiator.cs b/src/Tgstation.Server.Host/Core/IServerUpdateInitiator.cs index 43b730c3a3f..8b290bdcd2c 100644 --- a/src/Tgstation.Server.Host/Core/IServerUpdateInitiator.cs +++ b/src/Tgstation.Server.Host/Core/IServerUpdateInitiator.cs @@ -17,7 +17,7 @@ public interface IServerUpdateInitiator /// The optional used to retrieve the target server . If not provided, GitHub will be used. /// The TGS to update to. /// The for the operation. - /// A resulting in the . - Task InitiateUpdate(IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask InitiateUpdate(IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Core/IServerUpdater.cs b/src/Tgstation.Server.Host/Core/IServerUpdater.cs index d7f6d02b6e4..6485ed47134 100644 --- a/src/Tgstation.Server.Host/Core/IServerUpdater.cs +++ b/src/Tgstation.Server.Host/Core/IServerUpdater.cs @@ -19,7 +19,7 @@ interface IServerUpdater /// The optional used to retrieve the target server . If not provided, GitHub will be used. /// The TGS to update to. /// The for the operation. - /// A resulting in the . - Task BeginUpdate(ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken); + /// A resulting in the . + ValueTask BeginUpdate(ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Core/ServerUpdateInitiator.cs b/src/Tgstation.Server.Host/Core/ServerUpdateInitiator.cs index 7e92b59b396..f7fad731229 100644 --- a/src/Tgstation.Server.Host/Core/ServerUpdateInitiator.cs +++ b/src/Tgstation.Server.Host/Core/ServerUpdateInitiator.cs @@ -32,7 +32,7 @@ public ServerUpdateInitiator(ISwarmService swarmService, IServerUpdater serverUp } /// - public Task InitiateUpdate(IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) + public ValueTask InitiateUpdate(IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) => serverUpdater.BeginUpdate(swarmService, fileStreamProvider, version, cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Core/ServerUpdater.cs b/src/Tgstation.Server.Host/Core/ServerUpdater.cs index 77d2ea3da4c..aacf44fd193 100644 --- a/src/Tgstation.Server.Host/Core/ServerUpdater.cs +++ b/src/Tgstation.Server.Host/Core/ServerUpdater.cs @@ -92,7 +92,7 @@ public ServerUpdater( } /// - public async Task BeginUpdate(ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) + public async ValueTask BeginUpdate(ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(swarmService); @@ -105,7 +105,7 @@ public async Task BeginUpdate(ISwarmService swarmService, IF } /// - public async Task ExecuteUpdate(string updatePath, CancellationToken cancellationToken, CancellationToken criticalCancellationToken) + public async ValueTask ExecuteUpdate(string updatePath, CancellationToken cancellationToken, CancellationToken criticalCancellationToken) { ArgumentNullException.ThrowIfNull(updatePath); @@ -194,10 +194,10 @@ public async Task ExecuteUpdate(string updatePath, CancellationToken cance /// Attempt to abort a prepared swarm update. /// /// The being thrown. - /// A representing the running operation. + /// A representing the running operation. /// A new containing and the swarm abort if thrown. /// Requires to be populated. - async Task TryAbort(Exception exception) + async ValueTask TryAbort(Exception exception) { try { @@ -214,9 +214,9 @@ async Task TryAbort(Exception exception) /// /// The directory the server update is initially extracted to. /// The for the operation. - /// A resulting in containing a new based on the of and if it needs to be kept active until the swarm commit. + /// A resulting in containing a new based on the of and if it needs to be kept active until the swarm commit. /// Requires to be populated. - async Task> PrepareUpdateClearStagingAndBufferStream(string stagingDirectory, CancellationToken cancellationToken) + async ValueTask> PrepareUpdateClearStagingAndBufferStream(string stagingDirectory, CancellationToken cancellationToken) { await using var fileStreamProvider = serverUpdateOperation.FileStreamProvider; @@ -273,8 +273,8 @@ async Task> PrepareUpdateClearStagingAnd /// The TGS to update to. /// If this is a recursive call. /// The for the operation. - /// A resulting in the . - async Task BeginUpdateImpl( + /// A resulting in the . + async ValueTask BeginUpdateImpl( ISwarmService swarmService, IFileStreamProvider fileStreamProvider, Version newVersion, diff --git a/src/Tgstation.Server.Host/IServer.cs b/src/Tgstation.Server.Host/IServer.cs index 7ee759ec862..e13364831f6 100644 --- a/src/Tgstation.Server.Host/IServer.cs +++ b/src/Tgstation.Server.Host/IServer.cs @@ -17,7 +17,7 @@ public interface IServer /// Runs the . /// /// The for the operation. - /// A representing the running operation. - Task Run(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Run(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/IServerFactory.cs b/src/Tgstation.Server.Host/IServerFactory.cs index 7ec50612edb..46f95105231 100644 --- a/src/Tgstation.Server.Host/IServerFactory.cs +++ b/src/Tgstation.Server.Host/IServerFactory.cs @@ -21,7 +21,7 @@ public interface IServerFactory /// The arguments for the . /// The directory in which to install server updates. /// The for the operation. - /// A resulting in a new if it should be run, otherwise. - Task CreateServer(string[] args, string updatePath, CancellationToken cancellationToken); + /// A resulting in a new if it should be run, otherwise. + ValueTask CreateServer(string[] args, string updatePath, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Program.cs b/src/Tgstation.Server.Host/Program.cs index c3cb30fdbc9..e372c0563d6 100644 --- a/src/Tgstation.Server.Host/Program.cs +++ b/src/Tgstation.Server.Host/Program.cs @@ -40,7 +40,7 @@ public Program() /// Entrypoint for the . /// /// The command line arguments. - /// The . + /// A resulting in the . public static async Task Main(string[] args) { // first arg is 100% always the update path, starting it otherwise is solely for debugging purposes @@ -76,8 +76,8 @@ public static async Task Main(string[] args) /// /// The command line arguments, minus the . /// The path to extract server updates to be applied to. - /// The . - internal async Task Main(string[] args, string updatePath) + /// A resulting in the . + internal async ValueTask Main(string[] args, string updatePath) { try { diff --git a/src/Tgstation.Server.Host/Server.cs b/src/Tgstation.Server.Host/Server.cs index e3e3a6781c8..c99506805ba 100644 --- a/src/Tgstation.Server.Host/Server.cs +++ b/src/Tgstation.Server.Host/Server.cs @@ -110,7 +110,7 @@ public Server(IHostBuilder hostBuilder, string updatePath) } /// - public async Task Run(CancellationToken cancellationToken) + public async ValueTask Run(CancellationToken cancellationToken) { using (cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) using (var fsWatcher = updatePath != null ? new FileSystemWatcher(Path.GetDirectoryName(updatePath)) : null) @@ -240,19 +240,19 @@ public IRestartRegistration RegisterForRestart(IRestartHandler handler) } /// - public Task Restart() => RestartImpl(null, null, true, true); + public ValueTask Restart() => RestartImpl(null, null, true, true); /// - public Task GracefulShutdown(bool detach) => RestartImpl(null, null, false, detach); + public ValueTask GracefulShutdown(bool detach) => RestartImpl(null, null, false, detach); /// - public Task Die(Exception exception) + public ValueTask Die(Exception exception) { if (exception != null) return RestartImpl(null, exception, false, true); StopServerImmediate(); - return Task.CompletedTask; + return ValueTask.CompletedTask; } /// @@ -290,8 +290,8 @@ void CheckExceptionPropagation(Exception otherException) /// The potential value of . /// If the host watchdog is required for this "restart". /// If the restart should wait for extremely long running tasks to complete (Like the current DreamDaemon world). - /// A representing the running operation. - async Task RestartImpl(Version newVersion, Exception exception, bool requireWatchdog, bool completeAsap) + /// A representing the running operation. + async ValueTask RestartImpl(Version newVersion, Exception exception, bool requireWatchdog, bool completeAsap) { CheckSanity(requireWatchdog); diff --git a/src/Tgstation.Server.Host/ServerFactory.cs b/src/Tgstation.Server.Host/ServerFactory.cs index 2dd323022d9..9007f9bc58b 100644 --- a/src/Tgstation.Server.Host/ServerFactory.cs +++ b/src/Tgstation.Server.Host/ServerFactory.cs @@ -51,7 +51,7 @@ internal ServerFactory(IAssemblyInformationProvider assemblyInformationProvider, /// // TODO: Decomplexify #pragma warning disable CA1506 - public async Task CreateServer(string[] args, string updatePath, CancellationToken cancellationToken) + public async ValueTask CreateServer(string[] args, string updatePath, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(args); diff --git a/tests/Tgstation.Server.Host.Tests.Signals/Program.cs b/tests/Tgstation.Server.Host.Tests.Signals/Program.cs index eaebbc68f57..807fea235a1 100644 --- a/tests/Tgstation.Server.Host.Tests.Signals/Program.cs +++ b/tests/Tgstation.Server.Host.Tests.Signals/Program.cs @@ -22,7 +22,7 @@ static async Task Main() mockServerControl .Setup(x => x.GracefulShutdown(It.IsAny())) .Callback(() => tcs.SetResult()) - .Returns(Task.CompletedTask); + .Returns(ValueTask.CompletedTask); var mockAsyncDelayer = new Mock(); mockAsyncDelayer.Setup(x => x.Delay(It.IsAny(), It.IsAny())).Returns(Task.CompletedTask); diff --git a/tests/Tgstation.Server.Host.Tests/Core/TestServerUpdateInitiator.cs b/tests/Tgstation.Server.Host.Tests/Core/TestServerUpdateInitiator.cs index 9cffe2f180a..41bde8f5887 100644 --- a/tests/Tgstation.Server.Host.Tests/Core/TestServerUpdateInitiator.cs +++ b/tests/Tgstation.Server.Host.Tests/Core/TestServerUpdateInitiator.cs @@ -31,7 +31,7 @@ public void TestInitiateUpdate() var testVersion = new Version(Random.Shared.Next(), Random.Shared.Next(), Random.Shared.Next()); - mockServerUpdater.Setup(x => x.BeginUpdate(mockSwarmService, It.IsAny(), testVersion, It.IsAny())).Returns(Task.FromResult(ServerUpdateResult.Started)).Verifiable(); + mockServerUpdater.Setup(x => x.BeginUpdate(mockSwarmService, It.IsAny(), testVersion, It.IsAny())).Returns(ValueTask.FromResult(ServerUpdateResult.Started)).Verifiable(); var updateInitiator = new ServerUpdateInitiator(mockSwarmService, mockServerUpdater.Object); Assert.IsTrue(updateInitiator.InitiateUpdate(mockFileProvider, testVersion, default).IsCompleted); diff --git a/tests/Tgstation.Server.Host.Tests/TestProgram.cs b/tests/Tgstation.Server.Host.Tests/TestProgram.cs index 67c3546d0c0..f04531154f0 100644 --- a/tests/Tgstation.Server.Host.Tests/TestProgram.cs +++ b/tests/Tgstation.Server.Host.Tests/TestProgram.cs @@ -27,7 +27,7 @@ public async Task TestIncompatibleWatchdog() public async Task TestStandardRun() { var mockServer = new Mock(); - mockServer.Setup(x => x.Run(It.IsAny())).Returns(Task.CompletedTask); + mockServer.Setup(x => x.Run(It.IsAny())).Returns(ValueTask.CompletedTask); mockServer.SetupGet(x => x.RestartRequested).Returns(false); var mockServerFactory = new Mock(); mockServerFactory.Setup(x => x.CreateServer(It.IsNotNull(), It.IsAny(), It.IsAny())).ReturnsAsync(mockServer.Object); @@ -45,7 +45,7 @@ public async Task TestStandardRun() public async Task TestStandardRunWithRestart() { var mockServer = new Mock(); - mockServer.Setup(x => x.Run(It.IsAny())).Returns(Task.CompletedTask); + mockServer.Setup(x => x.Run(It.IsAny())).Returns(ValueTask.CompletedTask); mockServer.SetupGet(x => x.RestartRequested).Returns(true); var mockServerFactory = new Mock(); mockServerFactory.Setup(x => x.CreateServer(It.IsNotNull(), It.IsAny(), It.IsAny())).ReturnsAsync(mockServer.Object); @@ -73,7 +73,7 @@ public async Task TestStandardRunWithException() ServerFactory = mockServerFactory.Object }; - await Assert.ThrowsExceptionAsync(() => program.Main(Array.Empty(), null)); + await Assert.ThrowsExceptionAsync(() => program.Main(Array.Empty(), null).AsTask()); } [TestMethod] diff --git a/tests/Tgstation.Server.Host.Tests/TestServerFactory.cs b/tests/Tgstation.Server.Host.Tests/TestServerFactory.cs index f5a41b74d90..c8c83fc5942 100644 --- a/tests/Tgstation.Server.Host.Tests/TestServerFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/TestServerFactory.cs @@ -30,7 +30,7 @@ public async Task TestWorksWithoutUpdatePath() { var factory = Application.CreateDefaultServerFactory(); - await Assert.ThrowsExceptionAsync(() => factory.CreateServer(null, null, default)); + await Assert.ThrowsExceptionAsync(() => factory.CreateServer(null, null, default).AsTask()); var result = await factory.CreateServer(new[] { "General:SetupWizardMode=Never" }, null, default); Assert.IsNotNull(result); } @@ -41,8 +41,8 @@ public async Task TestWorksWithUpdatePath() var factory = Application.CreateDefaultServerFactory(); const string Path = "/test"; - await Assert.ThrowsExceptionAsync(() => factory.CreateServer(null, null, default)); - await Assert.ThrowsExceptionAsync(() => factory.CreateServer(null, Path, default)); + await Assert.ThrowsExceptionAsync(() => factory.CreateServer(null, null, default).AsTask()); + await Assert.ThrowsExceptionAsync(() => factory.CreateServer(null, Path, default).AsTask()); var result = await factory.CreateServer(new[] { "General:SetupWizardMode=Never" }, Path, default); Assert.IsNotNull(result); } diff --git a/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs index 56263c17171..0f725cf11d0 100644 --- a/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs +++ b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs @@ -181,7 +181,7 @@ public void UpdateSwarmArguments(SwarmConfiguration swarmConfiguration) swarmNodeId = swarmConfiguration.Identifier; } - public async Task RunNoArgumentsTest(CancellationToken cancellationToken) + public async ValueTask RunNoArgumentsTest(CancellationToken cancellationToken) { Assert.IsNull(Environment.GetEnvironmentVariable("General:SetupWizardMode")); Environment.SetEnvironmentVariable("General:SetupWizardMode", "Never"); @@ -194,7 +194,7 @@ await Application Environment.SetEnvironmentVariable("General:SetupWizardMode", null); } - public async Task Run(CancellationToken cancellationToken) + public async ValueTask Run(CancellationToken cancellationToken) { var messageAddition = swarmNodeId != null ? $": {swarmNodeId}" : String.Empty; System.Console.WriteLine("TEST SERVER START" + messageAddition); diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index cb6fd37442f..fbfd2d92e6c 100644 --- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -231,7 +231,7 @@ public async Task TestUpdateProtocolAndDisabledOAuth() using var server = new LiveTestingServer(null, false); using var serverCts = new CancellationTokenSource(); var cancellationToken = serverCts.Token; - var serverTask = server.Run(cancellationToken); + var serverTask = server.Run(cancellationToken).AsTask(); try { async ValueTask TestWithoutAndWithPermission(Func> action, IServerClient client, AdministrationRights right) @@ -333,7 +333,7 @@ async Task CheckUpdate() if (String.IsNullOrWhiteSpace(gitHubToken)) gitHubToken = null; await new Host.IO.DefaultIOManager().DeleteDirectory(server.UpdatePath, cancellationToken); - serverTask = server.Run(cancellationToken); + serverTask = server.Run(cancellationToken).AsTask(); using (var adminClient = await CreateAdminClient(server.Url, cancellationToken)) { @@ -437,7 +437,7 @@ public async Task TestOneServerSwarmUpdate() using var serverCts = new CancellationTokenSource(); serverCts.CancelAfter(TimeSpan.FromHours(3)); var cancellationToken = serverCts.Token; - var serverTask = controller.Run(cancellationToken); + var serverTask = controller.Run(cancellationToken).AsTask(); try { @@ -537,9 +537,9 @@ public async Task TestSwarmSynchronizationAndUpdates() using var serverCts = new CancellationTokenSource(); var cancellationToken = serverCts.Token; var serverTask = Task.WhenAll( - node1.Run(cancellationToken), - node2.Run(cancellationToken), - controller.Run(cancellationToken)); + node1.Run(cancellationToken).AsTask(), + node2.Run(cancellationToken).AsTask(), + controller.Run(cancellationToken).AsTask()); try { @@ -681,8 +681,8 @@ void CheckServerUpdated(LiveTestingServer server) UpdateRequiredNodeCount = 2, }); serverTask = Task.WhenAll( - controller.Run(cancellationToken), - node1.Run(cancellationToken)); + controller.Run(cancellationToken).AsTask(), + node1.Run(cancellationToken).AsTask()); using var controllerClient2 = await CreateAdminClient(controller.Url, cancellationToken); using var node1Client2 = await CreateAdminClient(node1.Url, cancellationToken); @@ -698,7 +698,7 @@ await ApiAssert.ThrowsException(() = // regression: test updating also works from the controller serverTask = Task.WhenAll( serverTask, - node2.Run(cancellationToken)); + node2.Run(cancellationToken).AsTask()); using var node2Client2 = await CreateAdminClient(node2.Url, cancellationToken); @@ -808,9 +808,9 @@ public async Task TestSwarmReconnection() Task node1Task, node2Task, controllerTask; var serverTask = Task.WhenAll( - node1Task = node1.Run(node1Cts.Token), - node2Task = node2.Run(cancellationToken), - controllerTask = controller.Run(cancellationToken)); + node1Task = node1.Run(node1Cts.Token).AsTask(), + node2Task = node2.Run(cancellationToken).AsTask(), + controllerTask = controller.Run(cancellationToken).AsTask()); try { @@ -895,7 +895,7 @@ await Task.WhenAny( Task.Delay(TimeSpan.FromMinutes(1), cancellationToken)); Assert.IsTrue(controllerTask.IsCompleted); - controllerTask = controller.Run(cancellationToken); + controllerTask = controller.Run(cancellationToken).AsTask(); using var controllerClient2 = await CreateAdminClient(controller.Url, cancellationToken); // node 2 should reconnect once it's health check triggers @@ -932,7 +932,7 @@ await ApiAssert.ThrowsException( cancellationToken), ErrorCode.SwarmIntegrityCheckFailed); - node2Task = node2.Run(cancellationToken); + node2Task = node2.Run(cancellationToken).AsTask(); using var node2Client2 = await CreateAdminClient(node2.Url, cancellationToken); // should re-register @@ -1060,7 +1060,7 @@ async Task TestTgsInternal(CancellationToken hardCancellationToken) InstanceManager GetInstanceManager() => ((Host.Server)server.RealServer).Host.Services.GetRequiredService(); // main run - var serverTask = server.Run(cancellationToken); + var serverTask = server.Run(cancellationToken).AsTask(); var fileDownloader = ((Host.Server)server.RealServer).Host.Services.GetRequiredService(); try @@ -1205,7 +1205,7 @@ await FailFast( var preStartupTime = DateTimeOffset.UtcNow; // chat bot start and DD reattach test - serverTask = server.Run(cancellationToken); + serverTask = server.Run(cancellationToken).AsTask(); using (var adminClient = await CreateAdminClient(server.Url, cancellationToken)) { var instanceClient = adminClient.Instances.CreateClient(instance); @@ -1306,7 +1306,7 @@ async Task WaitForInitialJobs(IInstanceClient instanceClient) // chat bot start, dd autostart, and reboot with different initial job test preStartupTime = DateTimeOffset.UtcNow; - serverTask = server.Run(cancellationToken); + serverTask = server.Run(cancellationToken).AsTask(); long expectedCompileJobId, expectedStaged; var edgeByond = await ByondTest.GetEdgeVersion(fileDownloader, cancellationToken); using (var adminClient = await CreateAdminClient(server.Url, cancellationToken)) @@ -1355,7 +1355,7 @@ await instanceClient.DreamDaemon.Update(new DreamDaemonRequest Assert.IsTrue(serverTask.IsCompleted); // post/entity deletion tests - serverTask = server.Run(cancellationToken); + serverTask = server.Run(cancellationToken).AsTask(); using (var adminClient = await CreateAdminClient(server.Url, cancellationToken)) { var instanceClient = adminClient.Instances.CreateClient(instance); From faeb730ebe9da6b084c9594eb96d6654db2589ba Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 17:31:50 -0400 Subject: [PATCH 22/33] Penultimate ValueTask conversion --- .../Components/InstanceManager.cs | 7 ++++--- .../Components/Repository/Repository.cs | 3 +++ .../Controllers/HomeController.cs | 7 +++---- .../Controllers/LimitedStreamResult.cs | 2 +- .../Database/DatabaseContextFactory.cs | 2 +- .../Database/IDatabaseContextFactory.cs | 2 +- .../IO/BufferedFileStreamProvider.cs | 4 ++-- .../IO/IFileStreamProvider.cs | 4 ++-- .../IO/ISeekableFileStreamProvider.cs | 4 ++-- .../IO/RequestFileStreamProvider.cs | 2 +- src/Tgstation.Server.Host/Jobs/IJobManager.cs | 8 ++++---- src/Tgstation.Server.Host/Jobs/JobService.cs | 17 +++++++++-------- .../Security/AuthenticationContextFactory.cs | 2 +- .../Security/IAuthenticationContextFactory.cs | 4 ++-- .../Security/ISystemIdentityFactory.cs | 4 ++-- .../Security/ITokenFactory.cs | 4 ++-- .../Security/OAuth/GenericOAuthValidator.cs | 8 ++++---- .../Security/OAuth/GitHubOAuthValidator.cs | 8 ++++---- .../Security/OAuth/IOAuthProviders.cs | 7 ++----- .../Security/OAuth/IOAuthValidator.cs | 9 ++++----- .../Security/OAuth/OAuthProviders.cs | 12 ++++-------- .../Security/TokenFactory.cs | 2 +- .../Transfer/FileUploadProvider.cs | 4 ++-- .../Chat/Providers/TestDiscordProvider.cs | 2 +- .../Chat/Providers/TestIrcProvider.cs | 2 +- .../IO/TestRequestFileStreamProvider.cs | 6 +++--- .../Swarm/TestableSwarmNode.cs | 2 +- .../CachingFileDownloader.cs | 2 +- 28 files changed, 68 insertions(+), 72 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs index f15847d80d9..eeae580d058 100644 --- a/src/Tgstation.Server.Host/Components/InstanceManager.cs +++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs @@ -11,6 +11,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Common; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components.Interop; using Tgstation.Server.Host.Components.Interop.Bridge; using Tgstation.Server.Host.Configuration; @@ -274,7 +275,7 @@ public async ValueTask MoveInstance(Models.Instance instance, string oldPath, Ca logger.LogDebug("Reverting instance {instanceId}'s path to {oldPath} in the DB...", instance.Id, oldPath); // DCT: Operation must always run - await databaseContextFactory.UseContext2(db => + await databaseContextFactory.UseContextTaskReturn(db => { var targetInstance = new Models.Instance { @@ -342,7 +343,7 @@ public async ValueTask OfflineInstance(Models.Instance metadata, Models.User use await container.OnZeroReferences.WaitAsync(cancellationToken); // we are the one responsible for cancelling his jobs - var tasks = new List(); + var tasks = new List>(); await databaseContextFactory.UseContext( async db => { @@ -359,7 +360,7 @@ await databaseContextFactory.UseContext( tasks.Add(jobService.CancelJob(job, user, true, cancellationToken)); }); - await Task.WhenAll(tasks); + await ValueTaskExtensions.WhenAll(tasks); } catch { diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs index a7dc2486921..928d873ae46 100644 --- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs @@ -7,6 +7,7 @@ using LibGit2Sharp; using LibGit2Sharp.Handlers; + using Microsoft.Extensions.Logging; using Tgstation.Server.Api.Models; @@ -20,6 +21,7 @@ namespace Tgstation.Server.Host.Components.Repository { /// +#pragma warning disable CA1506 // TODO: Decomplexify sealed class Repository : IRepository { /// @@ -1131,4 +1133,5 @@ TransferProgressHandler TransferProgressHandler(JobProgressReporter progressRepo return !cancellationToken.IsCancellationRequested; }; } +#pragma warning restore CA1506 } diff --git a/src/Tgstation.Server.Host/Controllers/HomeController.cs b/src/Tgstation.Server.Host/Controllers/HomeController.cs index a0be005e9e3..8aa6d3d03bc 100644 --- a/src/Tgstation.Server.Host/Controllers/HomeController.cs +++ b/src/Tgstation.Server.Host/Controllers/HomeController.cs @@ -145,16 +145,15 @@ public HomeController( /// /// Main page of the . /// - /// The for the operation. /// - /// A resuting in the containing of the if a properly authenticated API request, the web control panel if on a browser and enabled, otherwise. + /// The containing of the if a properly authenticated API request, the web control panel if on a browser and enabled, otherwise. /// /// retrieved successfully. [HttpGet] [AllowAnonymous] [ProducesResponseType(typeof(ServerInformationResponse), 200)] #pragma warning disable CA1506 - public async ValueTask Home(CancellationToken cancellationToken) + public IActionResult Home() { if (controlPanelConfiguration.Enable) Response.Headers.Add( @@ -201,7 +200,7 @@ public async ValueTask Home(CancellationToken cancellationToken) ValidInstancePaths = generalConfiguration.ValidInstancePaths, WindowsHost = platformIdentifier.IsWindows, SwarmServers = swarmService.GetSwarmServers(), - OAuthProviderInfos = await oAuthProviders.ProviderInfos(cancellationToken), + OAuthProviderInfos = oAuthProviders.ProviderInfos(), UpdateInProgress = serverControl.UpdateInProgress, }); } diff --git a/src/Tgstation.Server.Host/Controllers/LimitedStreamResult.cs b/src/Tgstation.Server.Host/Controllers/LimitedStreamResult.cs index 1917b53b175..734a1731a6d 100644 --- a/src/Tgstation.Server.Host/Controllers/LimitedStreamResult.cs +++ b/src/Tgstation.Server.Host/Controllers/LimitedStreamResult.cs @@ -48,6 +48,6 @@ public override Task ExecuteResultAsync(ActionContext context) } /// - public Task GetResult(CancellationToken cancellationToken) => Task.FromResult(stream); + public ValueTask GetResult(CancellationToken cancellationToken) => ValueTask.FromResult(stream); } } diff --git a/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs b/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs index 367b9f030f7..b04e32858b3 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseContextFactory.cs @@ -35,7 +35,7 @@ public async ValueTask UseContext(Func operation) } /// - public async ValueTask UseContext2(Func operation) + public async ValueTask UseContextTaskReturn(Func operation) { ArgumentNullException.ThrowIfNull(operation); diff --git a/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs b/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs index 228d34f498c..4004c873c08 100644 --- a/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs +++ b/src/Tgstation.Server.Host/Database/IDatabaseContextFactory.cs @@ -20,6 +20,6 @@ public interface IDatabaseContextFactory /// /// The operation to run. /// A representing the running . - ValueTask UseContext2(Func operation); + ValueTask UseContextTaskReturn(Func operation); } } diff --git a/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs b/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs index a31e076fb23..bf578ac7d45 100644 --- a/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs +++ b/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs @@ -77,14 +77,14 @@ public async ValueTask DisposeAsync() } /// - public async Task GetResult(CancellationToken cancellationToken) + public async ValueTask GetResult(CancellationToken cancellationToken) { var (sharedStream, _) = await GetResultInternal(cancellationToken); return sharedStream; } /// - public async Task GetOwnedResult(CancellationToken cancellationToken) + public async ValueTask GetOwnedResult(CancellationToken cancellationToken) { var (sharedStream, length) = await GetResultInternal(cancellationToken); return new MemoryStream(sharedStream.GetBuffer(), 0, (int)length, false, true); diff --git a/src/Tgstation.Server.Host/IO/IFileStreamProvider.cs b/src/Tgstation.Server.Host/IO/IFileStreamProvider.cs index 0660f878e40..e27f779314f 100644 --- a/src/Tgstation.Server.Host/IO/IFileStreamProvider.cs +++ b/src/Tgstation.Server.Host/IO/IFileStreamProvider.cs @@ -14,8 +14,8 @@ public interface IFileStreamProvider : IAsyncDisposable /// Gets the provided . May be called multiple times, though cancelling any may cause all calls to be cancelled. All calls yield the same reference. /// /// The for the operation. - /// A resulting in the provided on success, if it could not be provided. + /// A resulting in the provided on success, if it could not be provided. /// The resulting is owned by the and is short lived unless otherwise specified. It should be buffered if it needs use outside the lifetime of the . - Task GetResult(CancellationToken cancellationToken); + ValueTask GetResult(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/IO/ISeekableFileStreamProvider.cs b/src/Tgstation.Server.Host/IO/ISeekableFileStreamProvider.cs index b9e204008dc..7a6b76eb0d4 100644 --- a/src/Tgstation.Server.Host/IO/ISeekableFileStreamProvider.cs +++ b/src/Tgstation.Server.Host/IO/ISeekableFileStreamProvider.cs @@ -18,7 +18,7 @@ public interface ISeekableFileStreamProvider : IFileStreamProvider /// Gets the provided . May be called multiple times, though cancelling any may cause all calls to be cancelled. /// /// The for the operation. - /// A resulting in the provided on success, if it could not be provided. - Task GetOwnedResult(CancellationToken cancellationToken); + /// A resulting in the provided on success, if it could not be provided. + ValueTask GetOwnedResult(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/IO/RequestFileStreamProvider.cs b/src/Tgstation.Server.Host/IO/RequestFileStreamProvider.cs index 3404a508ebf..c0c100cfcf7 100644 --- a/src/Tgstation.Server.Host/IO/RequestFileStreamProvider.cs +++ b/src/Tgstation.Server.Host/IO/RequestFileStreamProvider.cs @@ -90,7 +90,7 @@ public async ValueTask DisposeAsync() } /// - public async Task GetResult(CancellationToken cancellationToken) + public async ValueTask GetResult(CancellationToken cancellationToken) { if (disposed) throw new ObjectDisposedException(nameof(RequestFileStreamProvider)); diff --git a/src/Tgstation.Server.Host/Jobs/IJobManager.cs b/src/Tgstation.Server.Host/Jobs/IJobManager.cs index 4741406a16d..716059f314f 100644 --- a/src/Tgstation.Server.Host/Jobs/IJobManager.cs +++ b/src/Tgstation.Server.Host/Jobs/IJobManager.cs @@ -33,8 +33,8 @@ public interface IJobManager /// 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 . + ValueTask WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken); /// /// Cancels a give . @@ -43,7 +43,7 @@ public interface IJobManager /// The who cancelled the . If the TGS user will be used. /// If the operation should wait until the job exits before completing. /// The for the operation. - /// A resulting in the updated if it was cancelled, if it couldn't be found. - Task CancelJob(Job job, User user, bool blocking, CancellationToken cancellationToken); + /// A resulting in the updated if it was cancelled, if it couldn't be found. + ValueTask CancelJob(Job job, User user, bool blocking, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs index e68b9a1333b..363a8eed28f 100644 --- a/src/Tgstation.Server.Host/Jobs/JobService.cs +++ b/src/Tgstation.Server.Host/Jobs/JobService.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging; using Serilog.Context; using Tgstation.Server.Api.Models.Response; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Components; using Tgstation.Server.Host.Database; using Tgstation.Server.Host.Extensions; @@ -172,9 +173,9 @@ public Task StartAsync(CancellationToken cancellationToken) .AsTask(); /// - public async Task StopAsync(CancellationToken cancellationToken) + public Task StopAsync(CancellationToken cancellationToken) { - List> joinTasks; + List> joinTasks; lock (addCancelLock) lock (synchronizationLock) { @@ -190,11 +191,11 @@ public async Task StopAsync(CancellationToken cancellationToken) .ToList(); } - await Task.WhenAll(joinTasks); + return ValueTaskExtensions.WhenAll(joinTasks).AsTask(); } /// - public async Task CancelJob(Job job, User user, bool blocking, CancellationToken cancellationToken) + public async ValueTask CancelJob(Job job, User user, bool blocking, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(job); @@ -248,7 +249,7 @@ public void SetJobProgress(JobResponse apiResponse) } /// - public async Task WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken) + public async ValueTask WaitForJobCompletion(Job job, User canceller, CancellationToken jobCancellationToken, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(job); @@ -268,12 +269,12 @@ public async Task WaitForJobCompletion(Job job, User canceller, CancellationToke if (noMoreJobsShouldStart && !handler.Started) await Extensions.TaskExtensions.InfiniteTask.WaitAsync(cancellationToken); - Task cancelTask = null; + ValueTask? cancelTask = null; using (jobCancellationToken.Register(() => cancelTask = CancelJob(job, canceller, true, cancellationToken))) await handler.Wait(cancellationToken); - if (cancelTask != null) - await cancelTask; + if (cancelTask.HasValue) + await cancelTask.Value; } /// diff --git a/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs b/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs index 51a51ad85b4..7288dc00cfb 100644 --- a/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs +++ b/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs @@ -62,7 +62,7 @@ public AuthenticationContextFactory( public void Dispose() => CurrentAuthenticationContext?.Dispose(); /// - public async Task CreateAuthenticationContext(long userId, long? instanceId, DateTimeOffset validAfter, CancellationToken cancellationToken) + public async ValueTask CreateAuthenticationContext(long userId, long? instanceId, DateTimeOffset validAfter, CancellationToken cancellationToken) { if (CurrentAuthenticationContext != null) throw new InvalidOperationException("Authentication context has already been loaded"); diff --git a/src/Tgstation.Server.Host/Security/IAuthenticationContextFactory.cs b/src/Tgstation.Server.Host/Security/IAuthenticationContextFactory.cs index d74d9529c69..9017765615f 100644 --- a/src/Tgstation.Server.Host/Security/IAuthenticationContextFactory.cs +++ b/src/Tgstation.Server.Host/Security/IAuthenticationContextFactory.cs @@ -21,7 +21,7 @@ public interface IAuthenticationContextFactory /// The of the operation. /// The the resulting 's password must be valid after. /// The for the operation. - /// A representing the running operation. - Task CreateAuthenticationContext(long userId, long? instanceId, DateTimeOffset validAfter, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CreateAuthenticationContext(long userId, long? instanceId, DateTimeOffset validAfter, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Security/ISystemIdentityFactory.cs b/src/Tgstation.Server.Host/Security/ISystemIdentityFactory.cs index 0a8f1874298..2568861e53a 100644 --- a/src/Tgstation.Server.Host/Security/ISystemIdentityFactory.cs +++ b/src/Tgstation.Server.Host/Security/ISystemIdentityFactory.cs @@ -21,7 +21,7 @@ public interface ISystemIdentityFactory /// /// The user to create a for. /// The for the operation. - /// A new or if the has no . + /// A resulting in a new based on the given or if the has no . Task CreateSystemIdentity(User user, CancellationToken cancellationToken); /// @@ -30,7 +30,7 @@ public interface ISystemIdentityFactory /// The username of the user. /// The password of the user. /// The for the operation. - /// A new . + /// A resulting in a new based on the given credentials. Task CreateSystemIdentity(string username, string password, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Security/ITokenFactory.cs b/src/Tgstation.Server.Host/Security/ITokenFactory.cs index 28e9273b461..6df27f813fd 100644 --- a/src/Tgstation.Server.Host/Security/ITokenFactory.cs +++ b/src/Tgstation.Server.Host/Security/ITokenFactory.cs @@ -23,7 +23,7 @@ public interface ITokenFactory /// The to create the token for. Must have the field available. /// Whether or not this is an OAuth login. /// The for the operation. - /// A resulting in a new . - Task CreateToken(Models.User user, bool oAuth, CancellationToken cancellationToken); + /// A resulting in a new . + ValueTask CreateToken(Models.User user, bool oAuth, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Security/OAuth/GenericOAuthValidator.cs b/src/Tgstation.Server.Host/Security/OAuth/GenericOAuthValidator.cs index 35c597bfcec..8606d0921d5 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/GenericOAuthValidator.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/GenericOAuthValidator.cs @@ -80,7 +80,7 @@ public GenericOAuthValidator( } /// - public async Task ValidateResponseCode(string code, CancellationToken cancellationToken) + public async ValueTask ValidateResponseCode(string code, CancellationToken cancellationToken) { using var httpClient = CreateHttpClient(); string tokenResponsePayload = null; @@ -140,13 +140,13 @@ public async Task ValidateResponseCode(string code, CancellationToken ca } /// - public Task GetProviderInfo(CancellationToken cancellationToken) => Task.FromResult( - new OAuthProviderInfo + public OAuthProviderInfo GetProviderInfo() + => new () { ClientId = OAuthConfiguration.ClientId, RedirectUri = OAuthConfiguration.RedirectUrl, ServerUrl = OAuthConfiguration.ServerUrl, - }); + }; /// /// Decode the token payload . diff --git a/src/Tgstation.Server.Host/Security/OAuth/GitHubOAuthValidator.cs b/src/Tgstation.Server.Host/Security/OAuth/GitHubOAuthValidator.cs index ae19b252ca8..f53fe8137c1 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/GitHubOAuthValidator.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/GitHubOAuthValidator.cs @@ -52,7 +52,7 @@ public GitHubOAuthValidator( } /// - public async Task ValidateResponseCode(string code, CancellationToken cancellationToken) + public async ValueTask ValidateResponseCode(string code, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(code); @@ -84,11 +84,11 @@ public async Task ValidateResponseCode(string code, CancellationToken ca } /// - public Task GetProviderInfo(CancellationToken cancellationToken) => Task.FromResult( - new OAuthProviderInfo + public OAuthProviderInfo GetProviderInfo() + => new () { ClientId = oAuthConfiguration.ClientId, RedirectUri = oAuthConfiguration.RedirectUrl, - }); + }; } } diff --git a/src/Tgstation.Server.Host/Security/OAuth/IOAuthProviders.cs b/src/Tgstation.Server.Host/Security/OAuth/IOAuthProviders.cs index 4ea0ce2f142..c8b8a7b1615 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/IOAuthProviders.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/IOAuthProviders.cs @@ -1,6 +1,4 @@ using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Tgstation.Server.Api.Models; @@ -21,8 +19,7 @@ public interface IOAuthProviders /// /// Gets a of the provider client IDs. /// - /// The for the operation. - /// A resulting in a anew of the active s. - Task> ProviderInfos(CancellationToken cancellationToken); + /// A new of the active s. + Dictionary ProviderInfos(); } } diff --git a/src/Tgstation.Server.Host/Security/OAuth/IOAuthValidator.cs b/src/Tgstation.Server.Host/Security/OAuth/IOAuthValidator.cs index bd3b25e9683..7f3ca57287f 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/IOAuthValidator.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/IOAuthValidator.cs @@ -18,16 +18,15 @@ public interface IOAuthValidator /// /// Gets the of validator. /// - /// The for the operation. - /// A resulting in the client ID of the validator on success, on failure. - Task GetProviderInfo(CancellationToken cancellationToken); + /// The client ID of the validator on success, on failure. + OAuthProviderInfo GetProviderInfo(); /// /// Validate a given OAuth response . /// /// The OAuth response string from web application. /// The for the operation. - /// A resulting in if authentication failed, if a rate limit occurred, and the validated otherwise. - Task ValidateResponseCode(string code, CancellationToken cancellationToken); + /// A resulting in if authentication failed, if a rate limit occurred, and the validated otherwise. + ValueTask ValidateResponseCode(string code, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs b/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs index 05458a4c07d..7a562668ee8 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -85,19 +83,17 @@ public OAuthProviders( public IOAuthValidator GetValidator(OAuthProvider oAuthProvider) => validators.FirstOrDefault(x => x.Provider == oAuthProvider); /// - public async Task> ProviderInfos(CancellationToken cancellationToken) + public Dictionary ProviderInfos() { var providersAndTasks = validators.ToDictionary( x => x.Provider, - x => x.GetProviderInfo(cancellationToken)); - - await Task.WhenAll(providersAndTasks.Values); + x => x.GetProviderInfo()); return providersAndTasks - .Where(x => x.Value.Result != null) + .Where(x => x.Value != null) .ToDictionary( x => x.Key, - x => x.Value.Result); + x => x.Value); } } } diff --git a/src/Tgstation.Server.Host/Security/TokenFactory.cs b/src/Tgstation.Server.Host/Security/TokenFactory.cs index cc5ff8a2705..81a96876f60 100644 --- a/src/Tgstation.Server.Host/Security/TokenFactory.cs +++ b/src/Tgstation.Server.Host/Security/TokenFactory.cs @@ -104,7 +104,7 @@ public TokenFactory( } /// - public async Task CreateToken(Models.User user, bool oAuth, CancellationToken cancellationToken) + public async ValueTask CreateToken(Models.User user, bool oAuth, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(user); diff --git a/src/Tgstation.Server.Host/Transfer/FileUploadProvider.cs b/src/Tgstation.Server.Host/Transfer/FileUploadProvider.cs index 69286cc52cb..9fe8250da5e 100644 --- a/src/Tgstation.Server.Host/Transfer/FileUploadProvider.cs +++ b/src/Tgstation.Server.Host/Transfer/FileUploadProvider.cs @@ -66,7 +66,7 @@ public ValueTask DisposeAsync() } /// - public async Task GetResult(CancellationToken cancellationToken) + public async ValueTask GetResult(CancellationToken cancellationToken) { using (cancellationToken.Register(() => streamTcs.TrySetCanceled(cancellationToken))) using (ticketExpiryCts.Token.Register(() => streamTcs.TrySetResult(null))) @@ -88,7 +88,7 @@ public void Expire() /// The containing uploaded data. /// The for the operation. /// A resulting in , otherwise. - public async Task Completion(Stream stream, CancellationToken cancellationToken) + public async ValueTask Completion(Stream stream, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(stream); 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 db7ee0b40b2..3943d052316 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 @@ public static void Initialize(TestContext _) .Returns(ValueTask.CompletedTask); mockSetup .Setup(x => x.WaitForJobCompletion(It.IsNotNull(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(Task.CompletedTask); + .Returns(ValueTask.CompletedTask); 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 7bf25186286..80a5e40b66e 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 @@ public async Task TestConnectAndDisconnect() .Returns(ValueTask.CompletedTask); mockSetup .Setup(x => x.WaitForJobCompletion(It.IsNotNull(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(Task.CompletedTask); + .Returns(ValueTask.CompletedTask); 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/IO/TestRequestFileStreamProvider.cs b/tests/Tgstation.Server.Host.Tests/IO/TestRequestFileStreamProvider.cs index 638fa965c55..a950ee6b9f8 100644 --- a/tests/Tgstation.Server.Host.Tests/IO/TestRequestFileStreamProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/IO/TestRequestFileStreamProvider.cs @@ -133,9 +133,9 @@ public async Task TestInterruptedDownload() cts2.Cancel(); - await Assert.ThrowsExceptionAsync(() => task1); - await Assert.ThrowsExceptionAsync(() => task2); - await Assert.ThrowsExceptionAsync(() => task3); + await Assert.ThrowsExceptionAsync(() => task1.AsTask()); + await Assert.ThrowsExceptionAsync(() => task2.AsTask()); + await Assert.ThrowsExceptionAsync(() => task3.AsTask()); mockHttpClient.VerifyAll(); } diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs index 0021948045c..31b39a83c2b 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs @@ -98,7 +98,7 @@ public TestableSwarmNode( .Setup(x => x.UseContext(It.IsNotNull>())) .Callback>((func) => func(mockDatabaseContext)); mockDBContextFactory - .Setup(x => x.UseContext2(It.IsNotNull>())) + .Setup(x => x.UseContextTaskReturn(It.IsNotNull>())) .Callback>((func) => func(mockDatabaseContext)); var mockHttpClientFactory = new Mock(); diff --git a/tests/Tgstation.Server.Tests/CachingFileDownloader.cs b/tests/Tgstation.Server.Tests/CachingFileDownloader.cs index 1ed2b172b7e..17dcbbfaf59 100644 --- a/tests/Tgstation.Server.Tests/CachingFileDownloader.cs +++ b/tests/Tgstation.Server.Tests/CachingFileDownloader.cs @@ -130,7 +130,7 @@ public ProviderPackage(ILogger logger, Uri url, string bearerToken) public ValueTask DisposeAsync() => ValueTask.CompletedTask; - public async Task GetResult(CancellationToken cancellationToken) + public async ValueTask GetResult(CancellationToken cancellationToken) => await CacheFile(logger, url, bearerToken, null, cancellationToken); } From 8b59884bf9c6d3a8062cedcce7d43178133278f7 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 17:41:19 -0400 Subject: [PATCH 23/33] Final ValueTask conversion --- .../PosixSignalChecker.cs | 2 +- src/Tgstation.Server.Host.Service/Program.cs | 4 +- .../ServerService.cs | 2 +- .../ISignalChecker.cs | 4 +- .../IWatchdog.cs | 4 +- .../NoopSignalChecker.cs | 4 +- .../Watchdog.cs | 2 +- .../Components/Byond/ByondInstallerBase.cs | 2 +- .../Components/Byond/IByondInstaller.cs | 4 +- .../Components/Chat/ChatManager.cs | 28 +++--- .../Components/Chat/IChatManager.cs | 12 +-- .../Chat/Providers/DiscordProvider.cs | 6 +- .../Components/Chat/Providers/IProvider.cs | 6 +- .../Components/Chat/Providers/IrcProvider.cs | 8 +- .../Components/Chat/Providers/Provider.cs | 8 +- .../Components/Deployment/DreamMaker.cs | 28 +++--- .../Deployment/SwappableDmbProvider.cs | 4 +- .../Components/Instance.cs | 2 +- .../Components/InstanceFactory.cs | 2 +- .../Components/InstanceManager.cs | 10 +-- .../Interop/Bridge/IBridgeDispatcher.cs | 4 +- .../Components/Interop/Chunker.cs | 6 +- .../Components/Repository/Repository.cs | 6 +- .../Components/Session/SessionController.cs | 18 ++-- .../Session/SessionControllerFactory.cs | 17 ++-- .../Components/Session/SessionPersistor.cs | 2 +- .../Components/StaticFiles/Configuration.cs | 44 ++++------ .../Components/Watchdog/WatchdogBase.cs | 8 +- .../Components/Watchdog/WindowsWatchdog.cs | 4 +- .../IO/BufferedFileStreamProvider.cs | 4 +- .../IO/DefaultIOManager.cs | 12 +-- src/Tgstation.Server.Host/IO/IIOManager.cs | 18 ++-- .../Setup/SetupWizard.cs | 60 ++++++------- .../Swarm/ISwarmOperations.cs | 16 ++-- .../Swarm/ISwarmService.cs | 8 +- .../Swarm/ISwarmServiceController.cs | 8 +- .../Swarm/ISwarmUpdateAborter.cs | 4 +- .../Swarm/SwarmService.cs | 87 ++++++++++--------- src/Tgstation.Server.Host/System/IProcess.cs | 5 +- .../System/IProcessBase.cs | 4 +- .../System/IProcessFeatures.cs | 7 +- .../System/PosixProcessFeatures.cs | 4 +- src/Tgstation.Server.Host/System/Process.cs | 6 +- .../System/WindowsProcessFeatures.cs | 10 +-- .../Transfer/FileTransferService.cs | 4 +- .../Transfer/IFileTransferStreamHandler.cs | 8 +- .../Utils/IPortAllocator.cs | 4 +- .../Utils/PortAllocator.cs | 2 +- .../TestProgram.cs | 2 +- .../TestServerService.cs | 6 +- .../IO/TestIOManager.cs | 8 +- .../Setup/TestSetupWizard.cs | 6 +- .../Swarm/TestSwarmProtocol.cs | 11 +-- .../Swarm/TestableSwarmNode.cs | 2 +- .../System/TestProcessFeatures.cs | 5 +- .../Live/Instance/ConfigurationTest.cs | 7 +- .../Live/Instance/TestBridgeHandler.cs | 2 +- 57 files changed, 285 insertions(+), 286 deletions(-) diff --git a/src/Tgstation.Server.Host.Console/PosixSignalChecker.cs b/src/Tgstation.Server.Host.Console/PosixSignalChecker.cs index a2ffceb69f0..e037b5936fb 100644 --- a/src/Tgstation.Server.Host.Console/PosixSignalChecker.cs +++ b/src/Tgstation.Server.Host.Console/PosixSignalChecker.cs @@ -31,7 +31,7 @@ public PosixSignalChecker(ILogger logger) } /// - public async Task CheckSignals(Func startChild, CancellationToken cancellationToken) + public async ValueTask CheckSignals(Func startChild, CancellationToken cancellationToken) { var (childPid, _) = startChild?.Invoke(null) ?? throw new ArgumentNullException(nameof(startChild)); var signalTcs = new TaskCompletionSource(); diff --git a/src/Tgstation.Server.Host.Service/Program.cs b/src/Tgstation.Server.Host.Service/Program.cs index bb12d5c8f74..9e6deaeb633 100644 --- a/src/Tgstation.Server.Host.Service/Program.cs +++ b/src/Tgstation.Server.Host.Service/Program.cs @@ -116,7 +116,7 @@ public async Task OnExecuteAsync() } if (Configure) - await RunConfigure(CancellationToken.None); // DCT: None available + await RunConfigure(CancellationToken.None); // DCT: None available bool stopped = false; if (Uninstall) @@ -281,7 +281,7 @@ void RestartService(ServiceController serviceController) /// /// The for the operation. /// A representing the running operation. - async Task RunConfigure(CancellationToken cancellationToken) + async ValueTask RunConfigure(CancellationToken cancellationToken) { using var loggerFactory = LoggerFactory.Create(builder => { diff --git a/src/Tgstation.Server.Host.Service/ServerService.cs b/src/Tgstation.Server.Host.Service/ServerService.cs index 978aee638e5..8f5554304fe 100644 --- a/src/Tgstation.Server.Host.Service/ServerService.cs +++ b/src/Tgstation.Server.Host.Service/ServerService.cs @@ -90,7 +90,7 @@ public ServerService(IWatchdogFactory watchdogFactory, string[] commandLineArgum } /// - public async Task CheckSignals(Func startChildAndGetPid, CancellationToken cancellationToken) + public async ValueTask CheckSignals(Func startChildAndGetPid, CancellationToken cancellationToken) { await using (commandPipeServer = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable)) await using (readyPipeServer = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable)) diff --git a/src/Tgstation.Server.Host.Watchdog/ISignalChecker.cs b/src/Tgstation.Server.Host.Watchdog/ISignalChecker.cs index 8ab3b06df69..b23295dd0fd 100644 --- a/src/Tgstation.Server.Host.Watchdog/ISignalChecker.cs +++ b/src/Tgstation.Server.Host.Watchdog/ISignalChecker.cs @@ -14,7 +14,7 @@ public interface ISignalChecker /// /// An to start the main process. It accepts an optional additional command line argument as a paramter and returns it's and lifetime . /// The for the operation. - /// A representing the running operation. - Task CheckSignals(Func startChild, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CheckSignals(Func startChild, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host.Watchdog/IWatchdog.cs b/src/Tgstation.Server.Host.Watchdog/IWatchdog.cs index a9c5dfb4a75..dadff2c41b3 100644 --- a/src/Tgstation.Server.Host.Watchdog/IWatchdog.cs +++ b/src/Tgstation.Server.Host.Watchdog/IWatchdog.cs @@ -20,7 +20,7 @@ public interface IWatchdog /// If the should just run the host configuration wizard and exit. /// The arguments for the . /// The for the operation. - /// A resulting in if there were no errors, otherwise. - Task RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken); + /// A resulting in if there were no errors, otherwise. + ValueTask RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host.Watchdog/NoopSignalChecker.cs b/src/Tgstation.Server.Host.Watchdog/NoopSignalChecker.cs index 409eed8fbc6..fa5dd56f946 100644 --- a/src/Tgstation.Server.Host.Watchdog/NoopSignalChecker.cs +++ b/src/Tgstation.Server.Host.Watchdog/NoopSignalChecker.cs @@ -10,11 +10,11 @@ namespace Tgstation.Server.Host.Watchdog public sealed class NoopSignalChecker : ISignalChecker { /// - public Task CheckSignals(Func startChild, CancellationToken cancellationToken) + public ValueTask CheckSignals(Func startChild, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(startChild); startChild(null); - return Task.CompletedTask; + return ValueTask.CompletedTask; } } } diff --git a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs index 21d60f52031..a13dc2f5f1b 100644 --- a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs +++ b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs @@ -46,7 +46,7 @@ public Watchdog(ISignalChecker signalChecker, ILogger logger) /// #pragma warning disable CA1502 // TODO: Decomplexify #pragma warning disable CA1506 - public async Task RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken) + public async ValueTask RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken) { logger.LogInformation("Host watchdog starting..."); int currentProcessId; diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs b/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs index 698f2a5563b..2478acdc1f7 100644 --- a/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs +++ b/src/Tgstation.Server.Host/Components/Byond/ByondInstallerBase.cs @@ -66,7 +66,7 @@ protected ByondInstallerBase(IIOManager ioManager, IFileDownloader fileDownloade public abstract string GetDreamDaemonName(Version version, out bool supportsCli, out bool supportsMapThreads); /// - public async ValueTask CleanCache(CancellationToken cancellationToken) + public async Task CleanCache(CancellationToken cancellationToken) { try { diff --git a/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs b/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs index e678068d627..9c353378303 100644 --- a/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Byond/IByondInstaller.cs @@ -59,7 +59,7 @@ interface IByondInstaller /// Attempts to cleans the BYOND cache folder for the system. /// /// The for the operation. - /// A representing the running operation. - ValueTask CleanCache(CancellationToken cancellationToken); + /// A representing the running operation. + Task CleanCache(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index 7c27d08d397..ecb0fa6498c 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -178,7 +178,7 @@ public async ValueTask DisposeAsync() } /// - public async Task ChangeChannels(long connectionId, IEnumerable newChannels, CancellationToken cancellationToken) + public async ValueTask ChangeChannels(long connectionId, IEnumerable newChannels, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(newChannels); @@ -261,7 +261,7 @@ public async Task ChangeChannels(long connectionId, IEnumerable - public async Task ChangeSettings(Models.ChatBot newSettings, CancellationToken cancellationToken) + public async ValueTask ChangeSettings(Models.ChatBot newSettings, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(newSettings); @@ -412,7 +412,7 @@ public Func> QueueDeploymentMessage( AddMessageTask(task); Task callbackTask; - Func finalUpdateAction = null; + Func finalUpdateAction = null; async Task CallbackTask(string errorMessage, string dreamMakerOutput) { await task; @@ -423,10 +423,10 @@ async Task CallbackTask(string errorMessage, string dreamMakerOutput) dreamMakerOutput)), callbacks.Count); - finalUpdateAction = active => ValueTaskExtensions.WhenAll(callbackResults.Select(finalizerCallback => finalizerCallback(active))); + finalUpdateAction = active => ValueTaskExtensions.WhenAll(callbackResults.Select(finalizerCallback => finalizerCallback(active))).AsTask(); } - async ValueTask CompletionTask(bool active) + async Task CompletionTask(bool active) { try { @@ -438,14 +438,14 @@ async ValueTask CompletionTask(bool active) return; } - AddMessageTask(finalUpdateAction(active).AsTask()); + AddMessageTask(finalUpdateAction(active)); } return (errorMessage, dreamMakerOutput) => { callbackTask = CallbackTask(errorMessage, dreamMakerOutput); AddMessageTask(callbackTask); - return active => AddMessageTask(CompletionTask(active).AsTask()); + return active => AddMessageTask(CompletionTask(active)); }; } @@ -455,7 +455,7 @@ public async Task StartAsync(CancellationToken cancellationToken) foreach (var tgsCommand in commandFactory.GenerateCommands()) builtinCommands.Add(tgsCommand.Name.ToUpperInvariant(), tgsCommand); var initialChatBots = activeChatBots.ToList(); - await Task.WhenAll(initialChatBots.Select(x => ChangeSettings(x, cancellationToken))); + await ValueTaskExtensions.WhenAll(initialChatBots.Select(x => ChangeSettings(x, cancellationToken))); initialProviderConnectionsTask = InitialConnection(); chatHandler = MonitorMessages(handlerCts.Token); } @@ -495,7 +495,7 @@ public IChatTrackingContext CreateTrackingContext() } /// - public async Task UpdateTrackingContexts(CancellationToken cancellationToken) + public async ValueTask UpdateTrackingContexts(CancellationToken cancellationToken) { var logMessageSent = 0; async Task UpdateTrackingContext(IChatTrackingContext channelSink, IEnumerable channels) @@ -589,8 +589,8 @@ public ValueTask HandleRestart(Version updateVersion, bool handlerMayDelayShutdo /// The of the to delete. /// If the provider should be removed from and should be update. /// The for the operation. - /// A resulting in the being removed if it exists, otherwise. - async Task RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken) + /// A resulting in the being removed if it exists, otherwise. + async ValueTask RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken) { logger.LogTrace("RemoveProviderChannels {connectionId}...", connectionId); IProvider provider; @@ -936,7 +936,7 @@ async Task MonitorMessages(CancellationToken cancellationToken) { logger.LogTrace("Starting processing loop..."); var messageTasks = new Dictionary>(); - Task activeProcessingTask = Task.CompletedTask; + ValueTask activeProcessingTask = ValueTask.CompletedTask; try { Task updatedTask = null; @@ -956,7 +956,7 @@ async Task MonitorMessages(CancellationToken cancellationToken) if (!messageTasks.ContainsKey(providerKvp.Value)) messageTasks.Add( providerKvp.Value, - providerKvp.Value.NextMessage(cancellationToken).AsTask()); + providerKvp.Value.NextMessage(cancellationToken)); if (messageTasks.Count == 0) { @@ -981,7 +981,7 @@ async Task MonitorMessages(CancellationToken cancellationToken) var message = await completedMessageTaskKvp.Value; var messageNumber = Interlocked.Increment(ref messagesProcessed); - async Task WrapProcessMessage() + async ValueTask WrapProcessMessage() { var localActiveProcessingTask = activeProcessingTask; using (LogContext.PushProperty(SerilogContextHelper.ChatMessageIterationContextProperty, messageNumber)) diff --git a/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs index f5ef9da42fc..769ab7b2515 100644 --- a/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs @@ -24,8 +24,8 @@ public interface IChatManager : IComponentService, IAsyncDisposable /// /// The new . /// The for the operation. - /// A representing the running operation. Will complete immediately if the property of is . - Task ChangeSettings(Models.ChatBot newSettings, CancellationToken cancellationToken); + /// A representing the running operation. Will complete immediately if the property of is . + ValueTask ChangeSettings(Models.ChatBot newSettings, CancellationToken cancellationToken); /// /// Disconnects and deletes a given connection. @@ -41,8 +41,8 @@ public interface IChatManager : IComponentService, IAsyncDisposable /// The of the connection. /// An of the new list of s. /// The for the operation. - /// A representing the running operation. - Task ChangeChannels(long connectionId, IEnumerable newChannels, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask ChangeChannels(long connectionId, IEnumerable newChannels, CancellationToken cancellationToken); /// /// Queue a chat to a given set of . @@ -85,7 +85,7 @@ Func> QueueDeploymentMessage( /// Force an update with the active channels on all active s. /// /// The for the operation. - /// A representing the running operation. - Task UpdateTrackingContexts(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask UpdateTrackingContexts(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index b30af6e0c97..fa6098c6e01 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -260,7 +260,7 @@ public override async ValueTask SendMessage(Message replyTo, MessageContent mess var embeds = ConvertEmbed(message.Embed); var channelsClient = serviceProvider.GetRequiredService(); - async Task SendToChannel(Snowflake channelId) + async ValueTask SendToChannel(Snowflake channelId) { var result = await channelsClient.CreateMessageAsync( channelId, @@ -312,7 +312,7 @@ await channelsClient.CreateMessageAsync( if (unmappedTextChannels.Any()) { Logger.LogDebug("Dispatching to {count} unmapped channels...", unmappedTextChannels.Count()); - await Task.WhenAll( + await ValueTaskExtensions.WhenAll( unmappedTextChannels.Select( x => SendToChannel(x.ID))); } @@ -430,7 +430,7 @@ public override async ValueTask - /// Get a resulting in the next the recieves or on a disconnect. + /// Get a resulting in the next the recieves or on a disconnect. /// /// The for the operation. - /// A resulting in the next available or if the needed to reconnect. + /// A resulting in the next available or if the needed to reconnect. /// Note that private messages will come in the form of s not returned in . - ValueTask NextMessage(CancellationToken cancellationToken); + Task NextMessage(CancellationToken cancellationToken); /// /// Gracefully disconnects the provider. Permanently stops the reconnection timer. diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs index b978687a714..c4449e00ea7 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs @@ -595,8 +595,8 @@ Task NonBlockingListen(CancellationToken cancellationToken) => Task.Factory.Star /// Run SASL authentication on . /// /// The for the operation. - /// A representing the running operation. - async Task SaslAuthenticate(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask SaslAuthenticate(CancellationToken cancellationToken) { client.WriteLine("CAP REQ :sasl", Priority.Critical); // needs to be put in the buffer before anything else cancellationToken.ThrowIfCancellationRequested(); @@ -665,8 +665,8 @@ await AsyncDelayer.Delay(listenTimeSpan, timeoutToken)) /// Attempt to disconnect from IRC immediately. /// /// The for the operation. - /// A representing the running operation. - async Task HardDisconnect(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask HardDisconnect(CancellationToken cancellationToken) { if (!Connected) { diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs index 90430565eff..88cd5b2e2c6 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs @@ -144,7 +144,7 @@ public async ValueTask - public async ValueTask NextMessage(CancellationToken cancellationToken) + public async Task NextMessage(CancellationToken cancellationToken) { while (true) { @@ -171,7 +171,7 @@ public Task SetReconnectInterval(uint reconnectInterval, bool connectNow) { stopOldTimerTask = StopReconnectionTimer(); reconnectCts = new CancellationTokenSource(); - reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token).AsTask(); + reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token); } return stopOldTimerTask; @@ -260,8 +260,8 @@ Task StopReconnectionTimer() /// The amount of minutes to wait between reconnection attempts. /// If a connection attempt should be immediately made. /// The for the operation. - /// A representing the running operation. - async ValueTask ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken) + /// A representing the running operation. + async Task ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken) { do { diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs index 6793fdfb7ff..30f6a555df5 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs @@ -422,8 +422,8 @@ await databaseContextFactory.UseContext( /// /// The to retrieve previous deployment s from. /// The for the operation. - /// A resulting in the average of the 10 previous deployments or if there are none. - async Task CalculateExpectedDeploymentTime(IDatabaseContext databaseContext, CancellationToken cancellationToken) + /// A resulting in the average of the 10 previous deployments or if there are none. + async ValueTask CalculateExpectedDeploymentTime(IDatabaseContext databaseContext, CancellationToken cancellationToken) { var previousCompileJobs = await databaseContext .CompileJobs @@ -462,8 +462,8 @@ await databaseContextFactory.UseContext( /// The optional estimated of the compilation. /// Whether or not the 's current commit exists on the remote repository. /// The for the operation. - /// A resulting in the completed . - async Task Compile( + /// A resulting in the completed . + async ValueTask Compile( Models.RevisionInformation revisionInformation, Api.Models.Internal.DreamMakerSettings dreamMakerSettings, DreamDaemonLaunchParameters launchParameters, @@ -557,8 +557,8 @@ await RunCompileJob( /// The to use. /// The to use. /// The for the operation. - /// A representing the running operation. - async Task RunCompileJob( + /// A representing the running operation. + async ValueTask RunCompileJob( JobProgressReporter progressReporter, Models.CompileJob job, Api.Models.Internal.DreamMakerSettings dreamMakerSettings, @@ -711,8 +711,8 @@ await eventConsumer.HandleEvent( /// The to report progress of the operation. /// A representing the duration to give progress over if any. /// The for the operation. - /// A representing the running operation. - async Task ProgressTask(JobProgressReporter progressReporter, TimeSpan? estimatedDuration, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask ProgressTask(JobProgressReporter progressReporter, TimeSpan? estimatedDuration, CancellationToken cancellationToken) { double? lastReport = estimatedDuration.HasValue ? 0 : null; progressReporter.ReportProgress(lastReport); @@ -774,8 +774,8 @@ async Task ProgressTask(JobProgressReporter progressReporter, TimeSpan? estimate /// If the API validation is required to complete the deployment. /// If output should be logged to the DreamDaemon Diagnostics folder. /// The for the operation. - /// A representing the running operation. - async Task VerifyApi( + /// A representing the running operation. + async ValueTask VerifyApi( uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, @@ -856,8 +856,8 @@ async Task VerifyApi( /// The path to the DreamMaker executable. /// The for the operation. /// The for the operation. - /// A representing the running operation. - async Task RunDreamMaker(string dreamMakerPath, Models.CompileJob job, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask RunDreamMaker(string dreamMakerPath, Models.CompileJob job, CancellationToken cancellationToken) { await using var dm = processExecutor.LaunchProcess( dreamMakerPath, @@ -887,8 +887,8 @@ async Task RunDreamMaker(string dreamMakerPath, Models.CompileJob job, Canc /// /// The for the operation. /// The for the operation. - /// A representing the running operation. - async Task ModifyDme(Models.CompileJob job, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask ModifyDme(Models.CompileJob job, CancellationToken cancellationToken) { var dmeFileName = String.Join('.', job.DmeName, DmeExtension); var dmePath = ioManager.ConcatPath(job.DirectoryName.ToString(), dmeFileName); diff --git a/src/Tgstation.Server.Host/Components/Deployment/SwappableDmbProvider.cs b/src/Tgstation.Server.Host/Components/Deployment/SwappableDmbProvider.cs index e4964532229..b3d8505e659 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/SwappableDmbProvider.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/SwappableDmbProvider.cs @@ -74,8 +74,8 @@ public SwappableDmbProvider(IDmbProvider baseProvider, IIOManager ioManager, ISy /// Make the active by replacing the live link with our . /// /// The for the operation. - /// A representing the running operation. - public async Task MakeActive(CancellationToken cancellationToken) + /// A representing the running operation. + public async ValueTask MakeActive(CancellationToken cancellationToken) { if (Interlocked.Exchange(ref swapped, 1) != 0) throw new InvalidOperationException("Already swapped!"); diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index f812c51e740..879478a207a 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -317,7 +317,7 @@ await repo.FetchOrigin( var hasDbChanges = false; RevisionInformation currentRevInfo = null; Models.Instance attachedInstance = null; - async Task UpdateRevInfo(string currentHead, bool onOrigin, IEnumerable updatedTestMerges) + async ValueTask UpdateRevInfo(string currentHead, bool onOrigin, IEnumerable updatedTestMerges) { if (currentRevInfo == null) { diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index 9667a9f6e80..6d9d7a8b61c 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -419,7 +419,7 @@ public async ValueTask CreateInstance(IBridgeRegistrar bridgeRegistra public Task StartAsync(CancellationToken cancellationToken) { CheckSystemCompatibility(); - return byondInstaller.CleanCache(cancellationToken).AsTask(); + return byondInstaller.CleanCache(cancellationToken); } /// diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs index eeae580d058..ec66af63b1d 100644 --- a/src/Tgstation.Server.Host/Components/InstanceManager.cs +++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs @@ -460,7 +460,7 @@ public async Task StopAsync(CancellationToken cancellationToken) var instanceFactoryStopTask = instanceFactory.StopAsync(cancellationToken); await jobService.StopAsync(cancellationToken); - async Task OfflineInstanceImmediate(IInstance instance, CancellationToken cancellationToken) + async ValueTask OfflineInstanceImmediate(IInstance instance, CancellationToken cancellationToken) { try { @@ -472,7 +472,7 @@ async Task OfflineInstanceImmediate(IInstance instance, CancellationToken cancel } } - await Task.WhenAll(instances.Select(x => OfflineInstanceImmediate(x.Value.Instance, cancellationToken))); + await ValueTaskExtensions.WhenAll(instances.Select(x => OfflineInstanceImmediate(x.Value.Instance, cancellationToken))); await instanceFactoryStopTask; await swarmServiceController.Shutdown(cancellationToken); @@ -490,7 +490,7 @@ async Task OfflineInstanceImmediate(IInstance instance, CancellationToken cancel } /// - public async Task ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) + public async ValueTask ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(parameters); @@ -650,8 +650,8 @@ void CheckSystemCompatibility() /// Initializes the connection to the TGS swarm. /// /// The for the operation. - /// A representing the running operation. - async Task InitializeSwarm(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask InitializeSwarm(CancellationToken cancellationToken) { SwarmRegistrationResult registrationResult; do diff --git a/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeDispatcher.cs b/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeDispatcher.cs index 2a7a9e00d74..82de2d66312 100644 --- a/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeDispatcher.cs +++ b/src/Tgstation.Server.Host/Components/Interop/Bridge/IBridgeDispatcher.cs @@ -13,7 +13,7 @@ public interface IBridgeDispatcher /// /// The to handle. /// The for the operation. - /// A resulting in the for the request or if the request could not be dispatched. - Task ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken); + /// A resulting in the for the request or if the request could not be dispatched. + ValueTask ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/Interop/Chunker.cs b/src/Tgstation.Server.Host/Components/Interop/Chunker.cs index 7363f3aee8a..d6a0c7c024e 100644 --- a/src/Tgstation.Server.Host/Components/Interop/Chunker.cs +++ b/src/Tgstation.Server.Host/Components/Interop/Chunker.cs @@ -63,9 +63,9 @@ protected Chunker(ILogger logger) /// The callback that generates a for a given error. /// The . /// The for the operation. - /// A resulting in the for the chunked request. - protected async Task ProcessChunk( - Func> completionCallback, + /// A resulting in the for the chunked request. + protected async ValueTask ProcessChunk( + Func> completionCallback, Func chunkErrorCallback, ChunkData chunk, CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs index 928d873ae46..46cc06fd8e5 100644 --- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs @@ -535,7 +535,7 @@ await ioMananger.CopyDirectory( if (postWriteHandler.NeedsPostWrite(src)) postWriteHandler.HandleWrite(dest); - return Task.CompletedTask; + return ValueTask.CompletedTask; }, ioMananger.ResolvePath(), path, @@ -992,8 +992,8 @@ PushOptions GeneratePushOptions(JobProgressReporter progressReporter, string use /// The password for the . /// If any events created should be marked as part of the deployment pipeline. /// The for the operation. - /// A representing the running operation. - async Task UpdateSubmodules( + /// A representing the running operation. + async ValueTask UpdateSubmodules( JobProgressReporter progressReporter, string username, string password, diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs index f4b340e4f52..d3749f0e9ff 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs @@ -362,7 +362,7 @@ public async ValueTask DisposeAsync() } /// - public async Task ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) + public async ValueTask ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(parameters); @@ -439,7 +439,7 @@ void LogCombinedResponse() (completedResponse, cancellationToken) => { fullResponse = completedResponse; - return Task.FromResult(null); + return ValueTask.FromResult(null); }, error => { @@ -574,7 +574,7 @@ public async ValueTask UpdateChannels(IEnumerable newChan cancellationToken); /// - public Task CreateDump(string outputFile, CancellationToken cancellationToken) => process.CreateDump(outputFile, cancellationToken); + public ValueTask CreateDump(string outputFile, CancellationToken cancellationToken) => process.CreateDump(outputFile, cancellationToken); /// /// The for . @@ -660,8 +660,8 @@ void CheckDisposed() /// /// The to handle. /// The for the operation. - /// A resulting in the for the request or if the request could not be dispatched. - async Task ProcessBridgeCommand(BridgeParameters parameters, CancellationToken cancellationToken) + /// A resulting in the for the request or if the request could not be dispatched. + async ValueTask ProcessBridgeCommand(BridgeParameters parameters, CancellationToken cancellationToken) { var response = new BridgeResponse(); switch (parameters.CommandType) @@ -828,8 +828,8 @@ BridgeResponse BridgeError(string message) /// /// The to send. /// The for the operation. - /// A resulting in the of the topic request. - async Task SendTopicRequest(TopicParameters parameters, CancellationToken cancellationToken) + /// A resulting in the of the topic request. + async ValueTask SendTopicRequest(TopicParameters parameters, CancellationToken cancellationToken) { parameters.AccessIdentifier = ReattachInformation.AccessIdentifier; @@ -971,8 +971,8 @@ string GenerateQueryString(TopicParameters parameters, out string json) /// The sanitized topic query string to send. /// If this is a priority message. If so, the topic will make 5 attempts to send unless BYOND reboots or exits. /// The for the operation. - /// A resulting in the of the topic request. - async Task SendRawTopic(string queryString, bool priority, CancellationToken cancellationToken) + /// A resulting in the of the topic request. + async ValueTask SendRawTopic(string queryString, bool priority, CancellationToken cancellationToken) { if (disposed) { diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index 97fee0a95eb..3bc79939c7d 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -239,6 +239,7 @@ public SessionControllerFactory( } /// + #pragma warning disable CA1506 // TODO: Decomplexify public async ValueTask LaunchNew( IDmbProvider dmbProvider, IByondExecutableLock currentByondLock, @@ -283,7 +284,7 @@ public async ValueTask LaunchNew( dmbProvider.CompileJob.Id); PortBindTest(launchParameters.Port.Value); - await CheckPagerIsNotRunning(cancellationToken); + await CheckPagerIsNotRunning(); string outputFilePath = null; var preserveLogFile = true; @@ -393,6 +394,7 @@ public async ValueTask LaunchNew( throw; } } +#pragma warning restore CA1506 /// public async ValueTask Reattach( @@ -647,9 +649,8 @@ RuntimeInformation CreateRuntimeInformation( /// /// Make sure the BYOND pager is not running. /// - /// The for the operation. - /// A representing the running operation. - async Task CheckPagerIsNotRunning(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask CheckPagerIsNotRunning() { if (!platformIdentifier.IsWindows) return; @@ -658,12 +659,12 @@ async Task CheckPagerIsNotRunning(CancellationToken cancellationToken) if (otherProcess == null) return; - var otherUsernameTask = otherProcess.GetExecutingUsername(cancellationToken); + var otherUsername = otherProcess.GetExecutingUsername(); + await using var ourProcess = processExecutor.GetCurrentProcess(); - var ourUserName = await ourProcess.GetExecutingUsername(cancellationToken); - var otherUserName = await otherUsernameTask; + var ourUsername = ourProcess.GetExecutingUsername(); - if (otherUserName.Equals(ourUserName, StringComparison.Ordinal)) + if (otherUsername.Equals(ourUsername, StringComparison.Ordinal)) throw new JobException(ErrorCode.DeploymentPagerRunning); } } diff --git a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs index 5b44e93c540..5c3819f8bea 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs @@ -95,7 +95,7 @@ public async ValueTask Load(CancellationToken cancellationT Models.ReattachInformation result = null; TimeSpan? topicTimeout = null; - async Task KillProcess(Models.ReattachInformation reattachInfo) + async ValueTask KillProcess(Models.ReattachInformation reattachInfo) { try { diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs index 067869b5393..2b19803126d 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs @@ -219,7 +219,7 @@ public async ValueTask CopyDMFilesTo(string dmeFile, st generalConfiguration.GetCopyDirectoryTaskThrottle(), cancellationToken); - await Task.WhenAll(dmeExistsTask, headFileExistsTask, tailFileExistsTask, copyTask); + await Task.WhenAll(dmeExistsTask, headFileExistsTask, tailFileExistsTask, copyTask.AsTask()); if (!dmeExistsTask.Result && !headFileExistsTask.Result && !tailFileExistsTask.Result) return null; @@ -396,26 +396,7 @@ void GetFileStream() /// public async ValueTask SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) { - async Task> GetIgnoreFiles() - { - var ignoreFileBytes = await ioManager.ReadAllBytes(StaticIgnorePath(), cancellationToken); - var ignoreFileText = Encoding.UTF8.GetString(ignoreFileBytes); - - var results = new List { StaticIgnoreFile }; - - // we don't want to lose trailing whitespace on linux - using (var reader = new StringReader(ignoreFileText)) - { - cancellationToken.ThrowIfCancellationRequested(); - var line = await reader.ReadLineAsync(); - if (!String.IsNullOrEmpty(line)) - results.Add(line); - } - - return results; - } - - IReadOnlyList ignoreFiles; + List ignoreFiles; async ValueTask SymlinkBase(bool files) { @@ -458,7 +439,20 @@ await ValueTaskExtensions.WhenAll(entries.Select(async file = using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken)) { await EnsureDirectories(cancellationToken); - ignoreFiles = await GetIgnoreFiles(); + var ignoreFileBytes = await ioManager.ReadAllBytes(StaticIgnorePath(), cancellationToken); + var ignoreFileText = Encoding.UTF8.GetString(ignoreFileBytes); + + ignoreFiles = new List { StaticIgnoreFile }; + + // we don't want to lose trailing whitespace on linux + using (var reader = new StringReader(ignoreFileText)) + { + cancellationToken.ThrowIfCancellationRequested(); + var line = await reader.ReadLineAsync(); + if (!String.IsNullOrEmpty(line)) + ignoreFiles.Add(line); + } + await ValueTaskExtensions.WhenAll(SymlinkBase(true), SymlinkBase(false)); } } @@ -705,7 +699,7 @@ public async ValueTask HandleEvent(EventType eventType, IEnumerable para /// /// The for the operation. /// A representing the running operation. - async Task EnsureDirectories(CancellationToken cancellationToken) + Task EnsureDirectories(CancellationToken cancellationToken) { async Task ValidateStaticFolder() { @@ -721,7 +715,7 @@ async Task ValidateCodeModsFolder() return; await ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken); - await Task.WhenAll( + await ValueTaskExtensions.WhenAll( ioManager.WriteAllBytes( ioManager.ConcatPath( CodeModificationsSubdirectory, @@ -736,7 +730,7 @@ await Task.WhenAll( cancellationToken)); } - await Task.WhenAll( + return Task.WhenAll( ValidateCodeModsFolder(), ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken), ValidateStaticFolder()); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index a7eb583a7d3..3847e26077c 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -395,8 +395,8 @@ await jobManager.RegisterOperation( } /// - public Task StopAsync(CancellationToken cancellationToken) => - TerminateNoLock(false, !releaseServers, cancellationToken); + public async Task StopAsync(CancellationToken cancellationToken) => + await TerminateNoLock(false, !releaseServers, cancellationToken); /// public async ValueTask Terminate(bool graceful, CancellationToken cancellationToken) @@ -1002,8 +1002,8 @@ bool CheckActivationReason(ref Task task, MonitorActivationReason testActivation /// If the termination will be delayed until a reboot is detected in the active server's DMAPI and this function will return immediately. /// If the termination will be announced using . /// The for the operation. - /// A representing the running operation. - async Task TerminateNoLock(bool graceful, bool announce, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask TerminateNoLock(bool graceful, bool announce, CancellationToken cancellationToken) { if (Status == WatchdogStatus.Offline) return; diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs index fd1ab5fb182..cdc5307352e 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs @@ -331,8 +331,8 @@ protected override async ValueTask HandleMonitorWakeup(MonitorAct /// Create the initial link to the live game directory using . /// /// The for the operation. - /// A representing the running operation. - Task InitialLink(CancellationToken cancellationToken) + /// A representing the running operation. + ValueTask InitialLink(CancellationToken cancellationToken) { Logger.LogTrace("Symlinking compile job..."); return ActiveSwappable.MakeActive(cancellationToken); diff --git a/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs b/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs index bf578ac7d45..a369f410478 100644 --- a/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs +++ b/src/Tgstation.Server.Host/IO/BufferedFileStreamProvider.cs @@ -95,14 +95,14 @@ public async ValueTask GetOwnedResult(CancellationToken cancellati /// /// The for the operation. /// A representing the running operation. - public Task EnsureBuffered(CancellationToken cancellationToken) => GetResultInternal(cancellationToken); + public Task EnsureBuffered(CancellationToken cancellationToken) => GetResultInternal(cancellationToken).AsTask(); /// /// Gets the shared and its . /// /// The for the operation. /// A resulting in and its . - async Task<(MemoryStream, long)> GetResultInternal(CancellationToken cancellationToken) + async ValueTask<(MemoryStream, long)> GetResultInternal(CancellationToken cancellationToken) { if (!buffered) using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken)) diff --git a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs index 23d36cafd59..8416ca9bf37 100644 --- a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs +++ b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs @@ -68,9 +68,9 @@ static void NormalizeAndDelete(DirectoryInfo dir, CancellationToken cancellation } /// - public async Task CopyDirectory( + public async ValueTask CopyDirectory( IEnumerable ignore, - Func postCopyCallback, + Func postCopyCallback, string src, string dest, int? taskThrottle, @@ -93,7 +93,7 @@ public async Task CopyDirectory( public string ConcatPath(params string[] paths) => Path.Combine(paths); /// - public async Task CopyFile(string src, string dest, CancellationToken cancellationToken) + public async ValueTask CopyFile(string src, string dest, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(src); ArgumentNullException.ThrowIfNull(dest); @@ -197,7 +197,7 @@ public Task MoveDirectory(string source, string destination, CancellationToken c TaskScheduler.Current); /// - public async Task ReadAllBytes(string path, CancellationToken cancellationToken) + public async ValueTask ReadAllBytes(string path, CancellationToken cancellationToken) { path = ResolvePath(path); await using var file = new FileStream( @@ -220,7 +220,7 @@ public async Task ReadAllBytes(string path, CancellationToken cancellati public virtual string ResolvePath(string path) => Path.GetFullPath(path ?? throw new ArgumentNullException(nameof(path))); /// - public async Task WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken) + public async ValueTask WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken) { await using var file = CreateAsyncSequentialWriteStream(path); await file.WriteAsync(contents, cancellationToken); @@ -345,7 +345,7 @@ IEnumerable CopyDirectoryImpl( string src, string dest, IEnumerable ignore, - Func postCopyCallback, + Func postCopyCallback, SemaphoreSlim semaphore, CancellationToken cancellationToken) { diff --git a/src/Tgstation.Server.Host/IO/IIOManager.cs b/src/Tgstation.Server.Host/IO/IIOManager.cs index 16be142e7da..045036e98cc 100644 --- a/src/Tgstation.Server.Host/IO/IIOManager.cs +++ b/src/Tgstation.Server.Host/IO/IIOManager.cs @@ -54,10 +54,10 @@ public interface IIOManager /// The destination directory path. /// The optional maximum number of simultaneous tasks allowed to execute. /// The for the operation. - /// A representing the running operation. - Task CopyDirectory( + /// A representing the running operation. + ValueTask CopyDirectory( IEnumerable ignore, - Func postCopyCallback, + Func postCopyCallback, string src, string dest, int? taskThrottle, @@ -84,8 +84,8 @@ Task CopyDirectory( /// /// The path of the file to read. /// A for the operation. - /// A that results in the contents of a file at . - Task ReadAllBytes(string path, CancellationToken cancellationToken); + /// A that results in the contents of a file at . + ValueTask ReadAllBytes(string path, CancellationToken cancellationToken); /// /// Returns directory names in a given . @@ -116,8 +116,8 @@ Task CopyDirectory( /// The path of the file to write. /// The contents of the file. /// A for the operation. - /// A representing the running operation. - Task WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken); /// /// Copy a file from to . @@ -125,8 +125,8 @@ Task CopyDirectory( /// The source file to copy. /// The destination path. /// A for the operation. - /// A representing the running operation. - Task CopyFile(string src, string dest, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CopyFile(string src, string dest, CancellationToken cancellationToken); /// /// Gets the directory portion of a given . diff --git a/src/Tgstation.Server.Host/Setup/SetupWizard.cs b/src/Tgstation.Server.Host/Setup/SetupWizard.cs index 40656cad2e0..a1a5717e8ca 100644 --- a/src/Tgstation.Server.Host/Setup/SetupWizard.cs +++ b/src/Tgstation.Server.Host/Setup/SetupWizard.cs @@ -137,8 +137,8 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken) /// The question . /// The optional default response if the user doesn't enter anything. /// The for the operation. - /// A resulting in if the user replied yes, otherwise. - async Task PromptYesNo(string question, bool? defaultResponse, CancellationToken cancellationToken) + /// A resulting in if the user replied yes, otherwise. + async ValueTask PromptYesNo(string question, bool? defaultResponse, CancellationToken cancellationToken) { do { @@ -167,8 +167,8 @@ async Task PromptYesNo(string question, bool? defaultResponse, Cancellatio /// Prompts the user to enter the port to host TGS on. /// /// The for the operation. - /// A resulting in the hosting port, or to use the default. - async Task PromptForHostingPort(CancellationToken cancellationToken) + /// A resulting in the hosting port, or to use the default. + async ValueTask PromptForHostingPort(CancellationToken cancellationToken) { await console.WriteAsync(null, true, cancellationToken); await console.WriteAsync("What port would you like to connect to TGS on?", true, cancellationToken); @@ -198,8 +198,8 @@ await console.WriteAsync( /// The database name (or path in the case of a database). /// Whether or not the database exists. /// The for the operation. - /// A representing the running operation. - async Task TestDatabaseConnection( + /// A representing the running operation. + async ValueTask TestDatabaseConnection( DbConnection testConnection, DatabaseConfiguration databaseConfiguration, string databaseName, @@ -290,8 +290,8 @@ async Task TestDatabaseConnection( /// /// The path to the potential SQLite database file. /// The for the operation. - /// A resulting in the SQLite database path to store in the configuration. - async Task ValidateNonExistantSqliteDBName(string databaseName, CancellationToken cancellationToken) + /// A resulting in the SQLite database path to store in the configuration. + async ValueTask ValidateNonExistantSqliteDBName(string databaseName, CancellationToken cancellationToken) { var dbPathIsRooted = Path.IsPathRooted(databaseName); var resolvedPath = ioManager.ResolvePath( @@ -343,8 +343,8 @@ async Task ValidateNonExistantSqliteDBName(string databaseName, Cancella /// /// If this is the user's first time here. /// The for the operation. - /// A resulting in the input . - async Task PromptDatabaseType(bool firstTime, CancellationToken cancellationToken) + /// A resulting in the input . + async ValueTask PromptDatabaseType(bool firstTime, CancellationToken cancellationToken) { if (firstTime) { @@ -392,9 +392,9 @@ await console.WriteAsync( /// Prompts the user to create a . /// /// The for the operation. - /// A resulting in the new . + /// A resulting in the new . #pragma warning disable CA1502 // TODO: Decomplexify - async Task ConfigureDatabase(CancellationToken cancellationToken) + async ValueTask ConfigureDatabase(CancellationToken cancellationToken) { bool firstTime = true; do @@ -656,8 +656,8 @@ void CreateTestConnection(string connectionString) => /// Prompts the user to create a . /// /// The for the operation. - /// A resulting in the new . - async Task ConfigureGeneral(CancellationToken cancellationToken) + /// A resulting in the new . + async ValueTask ConfigureGeneral(CancellationToken cancellationToken) { var newGeneralConfiguration = new GeneralConfiguration { @@ -714,8 +714,8 @@ async Task ConfigureGeneral(CancellationToken cancellation /// Prompts the user to create a . /// /// The for the operation. - /// A resulting in the new . - async Task ConfigureLogging(CancellationToken cancellationToken) + /// A resulting in the new . + async ValueTask ConfigureLogging(CancellationToken cancellationToken) { var fileLoggingConfiguration = new FileLoggingConfiguration(); await console.WriteAsync(null, true, cancellationToken); @@ -771,7 +771,7 @@ async Task ConfigureLogging(CancellationToken cancella } while (true); - async Task PromptLogLevel(string question) + async ValueTask PromptLogLevel(string question) { do { @@ -799,8 +799,8 @@ async Task ConfigureLogging(CancellationToken cancella /// Prompts the user to create a . /// /// The for the operation. - /// A resulting in the new . - async Task ConfigureElasticsearch(CancellationToken cancellationToken) + /// A resulting in the new . + async ValueTask ConfigureElasticsearch(CancellationToken cancellationToken) { var elasticsearchConfiguration = new ElasticsearchConfiguration(); await console.WriteAsync(null, true, cancellationToken); @@ -851,8 +851,8 @@ async Task ConfigureElasticsearch(CancellationToken /// Prompts the user to create a . /// /// The for the operation. - /// A resulting in the new . - async Task ConfigureControlPanel(CancellationToken cancellationToken) + /// A resulting in the new . + async ValueTask ConfigureControlPanel(CancellationToken cancellationToken) { var config = new ControlPanelConfiguration { @@ -881,8 +881,8 @@ async Task ConfigureControlPanel(CancellationToken ca /// Prompts the user to create a . /// /// The for the operation. - /// A resulting in the new . - async Task ConfigureSwarm(CancellationToken cancellationToken) + /// A resulting in the new . + async ValueTask ConfigureSwarm(CancellationToken cancellationToken) { var enable = await PromptYesNo("Enable swarm mode?", false, cancellationToken); if (!enable) @@ -896,7 +896,7 @@ async Task ConfigureSwarm(CancellationToken cancellationToke } while (String.IsNullOrWhiteSpace(identifer)); - async Task ParseAddress(string question) + async ValueTask ParseAddress(string question) { var first = true; Uri address; @@ -956,8 +956,8 @@ async Task ParseAddress(string question) /// The to save. /// The to save. /// The for the operation. - /// A representing the running operation. - async Task SaveConfiguration( + /// A representing the running operation. + async ValueTask SaveConfiguration( string userConfigFileName, ushort? hostingPort, DatabaseConfiguration databaseConfiguration, @@ -1027,8 +1027,8 @@ await ioManager.WriteAllBytes( /// /// The path to the settings json to build. /// The for the operation. - /// A representing the running operation. - async Task RunWizard(string userConfigFileName, CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask RunWizard(string userConfigFileName, CancellationToken cancellationToken) { // welcome message await console.WriteAsync($"Welcome to {Constants.CanonicalPackageName}!", true, cancellationToken); @@ -1067,8 +1067,8 @@ await SaveConfiguration( /// Check if it should and run the if necessary. /// /// The for the operation. - /// A representing the running operation. - async Task CheckRunWizard(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask CheckRunWizard(CancellationToken cancellationToken) { var setupWizardMode = generalConfiguration.SetupWizardMode; if (setupWizardMode == SetupWizardMode.Never) diff --git a/src/Tgstation.Server.Host/Swarm/ISwarmOperations.cs b/src/Tgstation.Server.Host/Swarm/ISwarmOperations.cs index a2cae0c47c4..a1c0a276cda 100644 --- a/src/Tgstation.Server.Host/Swarm/ISwarmOperations.cs +++ b/src/Tgstation.Server.Host/Swarm/ISwarmOperations.cs @@ -23,8 +23,8 @@ public interface ISwarmOperations : ISwarmUpdateAborter /// /// The . /// The for the operation. - /// A resulting in if the node is able to update, otherwise. - Task PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken); + /// A resulting in if the node is able to update, otherwise. + ValueTask PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken); /// /// Validate a given . @@ -39,23 +39,23 @@ public interface ISwarmOperations : ISwarmUpdateAborter /// The that is registering. /// The registration . /// The for the operation. - /// A resulting in if the registration was successful, otherwise. - Task RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken); + /// A resulting in if the registration was successful, otherwise. + ValueTask RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken); /// /// Attempt to unregister a node with a given with the controller. /// /// The registration . /// The for the operation. - /// A representing the running operation. - Task UnregisterNode(Guid registrationId, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask UnregisterNode(Guid registrationId, CancellationToken cancellationToken); /// /// Notify the controller that the node with the given is ready to commit or notify the node of the controller telling it to commit. /// /// The registration . /// The for the operation. - /// A representing the running operation. - Task RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Swarm/ISwarmService.cs b/src/Tgstation.Server.Host/Swarm/ISwarmService.cs index c8d38663201..9b863895402 100644 --- a/src/Tgstation.Server.Host/Swarm/ISwarmService.cs +++ b/src/Tgstation.Server.Host/Swarm/ISwarmService.cs @@ -24,15 +24,15 @@ public interface ISwarmService : ISwarmUpdateAborter /// The to relay to other nodes. /// The to update to. /// The for the operation. - /// A resulting in if the update should proceed, otherwise. - Task PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken); + /// A resulting in if the update should proceed, otherwise. + ValueTask PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken); /// /// Signal to the swarm that an update is ready to be applied. /// /// The for the operation. - /// A resulting in the . - Task CommitUpdate(CancellationToken cancellationToken); + /// A resulting in the . + ValueTask CommitUpdate(CancellationToken cancellationToken); /// /// Gets the list of s in the swarm, including the current one. diff --git a/src/Tgstation.Server.Host/Swarm/ISwarmServiceController.cs b/src/Tgstation.Server.Host/Swarm/ISwarmServiceController.cs index 5912232e048..34babd945ba 100644 --- a/src/Tgstation.Server.Host/Swarm/ISwarmServiceController.cs +++ b/src/Tgstation.Server.Host/Swarm/ISwarmServiceController.cs @@ -12,14 +12,14 @@ interface ISwarmServiceController /// Attempt to register with the swarm controller if not one, sets up the database otherwise. /// /// The for the operation. - /// A resulting in the . - Task Initialize(CancellationToken cancellationToken); + /// A resulting in the . + ValueTask Initialize(CancellationToken cancellationToken); /// /// Deregister with the swarm controller or put clients into querying state. /// /// The for the operation. - /// A representing the running operation. - Task Shutdown(CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask Shutdown(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Swarm/ISwarmUpdateAborter.cs b/src/Tgstation.Server.Host/Swarm/ISwarmUpdateAborter.cs index e3f59893f65..8d69505f272 100644 --- a/src/Tgstation.Server.Host/Swarm/ISwarmUpdateAborter.cs +++ b/src/Tgstation.Server.Host/Swarm/ISwarmUpdateAborter.cs @@ -10,8 +10,8 @@ public interface ISwarmUpdateAborter /// /// Attempt to abort an uncommitted update. /// - /// A representing the running operation. + /// A representing the running operation. /// This method does not accept a because aborting an update should never be cancelled. - Task AbortUpdate(); + ValueTask AbortUpdate(); } } diff --git a/src/Tgstation.Server.Host/Swarm/SwarmService.cs b/src/Tgstation.Server.Host/Swarm/SwarmService.cs index 317f97463e9..7340d4b25df 100644 --- a/src/Tgstation.Server.Host/Swarm/SwarmService.cs +++ b/src/Tgstation.Server.Host/Swarm/SwarmService.cs @@ -16,6 +16,7 @@ using Newtonsoft.Json; using Tgstation.Server.Api.Models.Response; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Common.Http; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Core; @@ -211,7 +212,7 @@ public SwarmService( public void Dispose() => serverHealthCheckCancellationTokenSource?.Dispose(); /// - public async Task AbortUpdate() + public async ValueTask AbortUpdate() { if (!SwarmMode) return; @@ -239,7 +240,7 @@ public async Task AbortUpdate() } /// - public async Task CommitUpdate(CancellationToken cancellationToken) + public async ValueTask CommitUpdate(CancellationToken cancellationToken) { if (!SwarmMode) return SwarmCommitResult.ContinueUpdateNonCommitted; @@ -311,7 +312,7 @@ public async Task CommitUpdate(CancellationToken cancellation // on the controller, we first need to signal for nodes to go ahead // if anything fails at this point, there's nothing we can do logger.LogDebug("Sending remote commit message to nodes..."); - async Task SendRemoteCommitUpdate(SwarmServerResponse swarmServer) + async ValueTask SendRemoteCommitUpdate(SwarmServerResponse swarmServer) { using var request = PrepareSwarmRequest( swarmServer, @@ -332,12 +333,13 @@ async Task SendRemoteCommitUpdate(SwarmServerResponse swarmServer) } } - Task task; + ValueTask task; lock (swarmServers) - task = Task.WhenAll( + task = ValueTaskExtensions.WhenAll( swarmServers .Where(x => !x.Controller) - .Select(SendRemoteCommitUpdate)); + .Select(SendRemoteCommitUpdate) + .ToList()); await task; return SwarmCommitResult.MustCommitUpdate; @@ -354,7 +356,7 @@ public ICollection GetSwarmServers() } /// - public Task PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) + public ValueTask PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(fileStreamProvider); @@ -371,7 +373,7 @@ public Task PrepareUpdate(ISeekableFileStreamProvider fileSt } /// - public async Task PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken) + public async ValueTask PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(updateRequest); @@ -385,7 +387,7 @@ public async Task PrepareUpdateFromController(SwarmUpdateRequest updateReq } /// - public async Task Initialize(CancellationToken cancellationToken) + public async ValueTask Initialize(CancellationToken cancellationToken) { if (SwarmMode) logger.LogInformation( @@ -418,11 +420,11 @@ await databaseContextFactory.UseContext( } /// - public async Task Shutdown(CancellationToken cancellationToken) + public async ValueTask Shutdown(CancellationToken cancellationToken) { logger.LogTrace("Begin Shutdown"); - async Task SendUnregistrationRequest(SwarmServerResponse swarmServer) + async ValueTask SendUnregistrationRequest(SwarmServerResponse swarmServer) { using var httpClient = httpClientFactory.CreateClient(); using var request = PrepareSwarmRequest( @@ -478,13 +480,14 @@ await databaseContextFactory.UseContext( if (updateOperation == null) { logger.LogInformation("Unregistering nodes..."); - Task task; + ValueTask task; lock (swarmServers) { - task = Task.WhenAll( + task = ValueTaskExtensions.WhenAll( swarmServers .Where(x => !x.Controller) - .Select(SendUnregistrationRequest)); + .Select(SendUnregistrationRequest) + .ToList()); swarmServers.RemoveRange(1, swarmServers.Count - 1); registrationIdsAndTimes.Clear(); } @@ -527,7 +530,7 @@ public bool ValidateRegistration(Guid registrationId) } /// - public async Task RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken) + public async ValueTask RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(node); @@ -586,7 +589,7 @@ public async Task RegisterNode(Api.Models.Internal.SwarmServer node, Guid } /// - public async Task RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken) + public async ValueTask RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken) { var localUpdateOperation = updateOperation; if (!swarmController) @@ -635,7 +638,7 @@ public async Task RemoteCommitRecieved(Guid registrationId, CancellationTo } /// - public async Task UnregisterNode(Guid registrationId, CancellationToken cancellationToken) + public async ValueTask UnregisterNode(Guid registrationId, CancellationToken cancellationToken) { logger.LogTrace("UnregisterNode {registrationId}", registrationId); await AbortUpdate(); @@ -667,14 +670,14 @@ public async Task UnregisterNode(Guid registrationId, CancellationToken cancella /// /// Sends out remote abort update requests. /// - /// A representing the running operation. + /// A representing the running operation. /// The aborted should be cleared out before calling this. This method does not accept a because aborting an update should never be cancelled. - Task RemoteAbortUpdate() + ValueTask RemoteAbortUpdate() { logger.LogInformation("Aborting swarm update!"); using var httpClient = httpClientFactory.CreateClient(); - async Task SendRemoteAbort(SwarmServerResponse swarmServer) + async ValueTask SendRemoteAbort(SwarmServerResponse swarmServer) { using var request = PrepareSwarmRequest( swarmServer, @@ -706,10 +709,11 @@ async Task SendRemoteAbort(SwarmServerResponse swarmServer) }); lock (swarmServers) - return Task.WhenAll( + return ValueTaskExtensions.WhenAll( swarmServers .Where(x => !x.Controller) - .Select(SendRemoteAbort)); + .Select(SendRemoteAbort) + .ToList()); } /// @@ -753,8 +757,8 @@ RequestFileStreamProvider CreateUpdateStreamProvider(SwarmServerResponse sourceN /// The containing the update package if this is the initiating server, otherwise. /// The . Must always have populated. If is , it must be fully populated. /// The for the operation. - /// A resulting in the . - async Task PrepareUpdateImpl(ISeekableFileStreamProvider initiatorProvider, SwarmUpdateRequest updateRequest, CancellationToken cancellationToken) + /// A resulting in the . + async ValueTask PrepareUpdateImpl(ISeekableFileStreamProvider initiatorProvider, SwarmUpdateRequest updateRequest, CancellationToken cancellationToken) { if (!SwarmMode) { @@ -916,8 +920,8 @@ async Task PrepareUpdateImpl(ISeekableFileStreamProvider ini /// The . Must always have populated. If is , it must be fully populated. /// The current . /// The for the operation. - /// A resulting in the . - async Task ControllerDistributedPrepareUpdate( + /// A resulting in the . + async ValueTask ControllerDistributedPrepareUpdate( ISeekableFileStreamProvider initiatorProvider, SwarmUpdateRequest updateRequest, SwarmUpdateOperation currentUpdateOperation, @@ -1056,8 +1060,8 @@ async Task ControllerDistributedPrepareUpdate( /// The containing the server update package. /// An of the involved . /// The for the operation. - /// A resulting in a new of unique s keyed by their . - async Task> CreateDownloadTickets( + /// A resulting in a new of unique s keyed by their . + async ValueTask> CreateDownloadTickets( ISeekableFileStreamProvider initiatorProvider, IReadOnlyCollection involvedServers, CancellationToken cancellationToken) @@ -1093,8 +1097,8 @@ async Task> CreateDownloadTickets( /// Ping each node to see that they are still running. /// /// The for the operation. - /// A representing the running operation. - async Task HealthCheckNodes(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask HealthCheckNodes(CancellationToken cancellationToken) { using var httpClient = httpClientFactory.CreateClient(); @@ -1102,7 +1106,7 @@ async Task HealthCheckNodes(CancellationToken cancellationToken) lock (swarmServers) currentSwarmServers = swarmServers.ToList(); - async Task HealthRequestForServer(SwarmServerResponse swarmServer) + async ValueTask HealthRequestForServer(SwarmServerResponse swarmServer) { using var request = PrepareSwarmRequest( swarmServer, @@ -1131,7 +1135,7 @@ async Task HealthRequestForServer(SwarmServerResponse swarmServer) } } - await Task.WhenAll( + await ValueTaskExtensions.WhenAll( currentSwarmServers .Where(node => !node.Controller && registrationIdsAndTimes.TryGetValue(node.Identifier, out var registrationAndTime) @@ -1170,8 +1174,8 @@ bool TriggerHealthCheck() /// Ping the swarm controller to see that it is still running. If need be, reregister. /// /// The for the operation. - /// A representing the running operation. - async Task HealthCheckController(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask HealthCheckController(CancellationToken cancellationToken) { using var httpClient = httpClientFactory.CreateClient(); @@ -1227,8 +1231,8 @@ async Task HealthCheckController(CancellationToken cancellationToken) /// Attempt to register the node with the controller. /// /// The for the operation. - /// A resulting in the . - async Task RegisterWithController(CancellationToken cancellationToken) + /// A resulting in the . + async ValueTask RegisterWithController(CancellationToken cancellationToken) { logger.LogInformation("Attempting to register with swarm controller at {controllerAddress}...", swarmConfiguration.ControllerAddress); var requestedRegistrationId = Guid.NewGuid(); @@ -1289,8 +1293,8 @@ async Task RegisterWithController(CancellationToken can /// Sends the controllers list of nodes to all nodes. /// /// The for the operation. - /// A representing the running operation. - async Task SendUpdatedServerListToNodes(CancellationToken cancellationToken) + /// A representing the running operation. + async ValueTask SendUpdatedServerListToNodes(CancellationToken cancellationToken) { List currentSwarmServers; lock (swarmServers) @@ -1308,7 +1312,7 @@ async Task SendUpdatedServerListToNodes(CancellationToken cancellationToken) logger.LogDebug("Sending updated server list to all {nodeCount} nodes...", currentSwarmServers.Count - 1); using var httpClient = httpClientFactory.CreateClient(); - async Task UpdateRequestForServer(SwarmServerResponse swarmServer) + async ValueTask UpdateRequestForServer(SwarmServerResponse swarmServer) { using var request = PrepareSwarmRequest( swarmServer, @@ -1336,10 +1340,11 @@ async Task UpdateRequestForServer(SwarmServerResponse swarmServer) } } - await Task.WhenAll( + await ValueTaskExtensions.WhenAll( currentSwarmServers .Where(x => !x.Controller) - .Select(UpdateRequestForServer)); + .Select(UpdateRequestForServer) + .ToList()); } /// diff --git a/src/Tgstation.Server.Host/System/IProcess.cs b/src/Tgstation.Server.Host/System/IProcess.cs index afe5f497ec4..aec3f0d7a38 100644 --- a/src/Tgstation.Server.Host/System/IProcess.cs +++ b/src/Tgstation.Server.Host/System/IProcess.cs @@ -39,8 +39,7 @@ interface IProcess : IProcessBase, IAsyncDisposable /// /// Get the name of the account executing the . /// - /// The for the operation. - /// A resulting in the name of the account executing the . - Task GetExecutingUsername(CancellationToken cancellationToken); + /// The name of the account executing the . + string GetExecutingUsername(); } } diff --git a/src/Tgstation.Server.Host/System/IProcessBase.cs b/src/Tgstation.Server.Host/System/IProcessBase.cs index 472b1cf63a7..8fc0bd4484e 100644 --- a/src/Tgstation.Server.Host/System/IProcessBase.cs +++ b/src/Tgstation.Server.Host/System/IProcessBase.cs @@ -34,7 +34,7 @@ interface IProcessBase /// /// The full path to the output file. /// The for the operation. - /// A representing the running operation. - Task CreateDump(string outputFile, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CreateDump(string outputFile, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/System/IProcessFeatures.cs b/src/Tgstation.Server.Host/System/IProcessFeatures.cs index 2b5f6a3f846..abfaca6b7bf 100644 --- a/src/Tgstation.Server.Host/System/IProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/IProcessFeatures.cs @@ -12,9 +12,8 @@ interface IProcessFeatures /// Get the name of the user executing a given . /// /// The . - /// The for the operation. /// The name of the user executing . - Task GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken); + string GetExecutingUsername(global::System.Diagnostics.Process process); /// /// Suspend a given . @@ -34,7 +33,7 @@ interface IProcessFeatures /// The to dump. /// The full path to the output file. /// The for the operation. - /// A representing the running operation. - Task CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken); + /// A representing the running operation. + ValueTask CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs index 1332203311f..0e1dab1d3cf 100644 --- a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs @@ -60,11 +60,11 @@ public void SuspendProcess(global::System.Diagnostics.Process process) } /// - public Task GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken) + public string GetExecutingUsername(global::System.Diagnostics.Process process) => throw new NotSupportedException(); /// - public async Task CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken) + public async ValueTask CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(process); ArgumentNullException.ThrowIfNull(outputFile); diff --git a/src/Tgstation.Server.Host/System/Process.cs b/src/Tgstation.Server.Host/System/Process.cs index ac122ce0ff0..ccda2f2153b 100644 --- a/src/Tgstation.Server.Host/System/Process.cs +++ b/src/Tgstation.Server.Host/System/Process.cs @@ -202,15 +202,15 @@ public void Resume() } /// - public async Task GetExecutingUsername(CancellationToken cancellationToken) + public string GetExecutingUsername() { - var result = await processFeatures.GetExecutingUsername(handle, cancellationToken); + var result = processFeatures.GetExecutingUsername(handle); logger.LogTrace("PID {pid} Username: {username}", Id, result); return result; } /// - public Task CreateDump(string outputFile, CancellationToken cancellationToken) + public ValueTask CreateDump(string outputFile, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(outputFile); diff --git a/src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs b/src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs index 8aed17b22ea..efbb029e0af 100644 --- a/src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs @@ -93,7 +93,7 @@ public void SuspendProcess(global::System.Diagnostics.Process process) } /// - public Task GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken) + public string GetExecutingUsername(global::System.Diagnostics.Process process) { string query = $"SELECT * FROM Win32_Process WHERE ProcessId = {process?.Id ?? throw new ArgumentNullException(nameof(process))}"; using var searcher = new ManagementObjectSearcher(query); @@ -106,21 +106,21 @@ public Task GetExecutingUsername(global::System.Diagnostics.Process proc ?.ToString(); if (!Int32.TryParse(returnString, out var returnVal)) - return Task.FromResult($"BAD RETURN PARSE: {returnString}"); + return $"BAD RETURN PARSE: {returnString}"; if (returnVal == 0) { // return DOMAIN\user string owner = argList.Last() + "\\" + argList.First(); - return Task.FromResult(owner); + return owner; } } - return Task.FromResult("NO OWNER"); + return "NO OWNER"; } /// - public async Task CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken) + public async ValueTask CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken) { try { diff --git a/src/Tgstation.Server.Host/Transfer/FileTransferService.cs b/src/Tgstation.Server.Host/Transfer/FileTransferService.cs index 22dee33c7c7..263bd2ba9c3 100644 --- a/src/Tgstation.Server.Host/Transfer/FileTransferService.cs +++ b/src/Tgstation.Server.Host/Transfer/FileTransferService.cs @@ -163,7 +163,7 @@ public IFileUploadTicket CreateUpload(FileUploadStreamKind streamKind) } /// - public async Task> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken) + public async ValueTask> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(ticket); @@ -217,7 +217,7 @@ public async Task> RetrieveDownloadStream(Fi } /// - public async Task SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken) + public async ValueTask SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(ticket); diff --git a/src/Tgstation.Server.Host/Transfer/IFileTransferStreamHandler.cs b/src/Tgstation.Server.Host/Transfer/IFileTransferStreamHandler.cs index ecfea79f517..75603c86841 100644 --- a/src/Tgstation.Server.Host/Transfer/IFileTransferStreamHandler.cs +++ b/src/Tgstation.Server.Host/Transfer/IFileTransferStreamHandler.cs @@ -18,15 +18,15 @@ public interface IFileTransferStreamHandler /// The . /// The with uploaded data. /// The for the operation. - /// if the upload completed successfully, otherwise. - Task SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken); + /// A resulting in if the upload completed successfully, otherwise. + ValueTask SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken); /// /// Gets the the for a given associated with a pending download. /// /// The . /// The for the operation. - /// A containing either a containing the data to download or an to return. - Task> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken); + /// A resulting in a containing either a containing the data to download or an to return. + ValueTask> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Utils/IPortAllocator.cs b/src/Tgstation.Server.Host/Utils/IPortAllocator.cs index 865107bb1ad..29d234ec62c 100644 --- a/src/Tgstation.Server.Host/Utils/IPortAllocator.cs +++ b/src/Tgstation.Server.Host/Utils/IPortAllocator.cs @@ -14,7 +14,7 @@ public interface IPortAllocator /// The port to check first. Will not allocate a port lower than this. /// If only should be checked and no others. /// The for the operation. - /// A resulting in the first available port on success, on failure. - Task GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken); + /// A resulting in the first available port on success, on failure. + ValueTask GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Utils/PortAllocator.cs b/src/Tgstation.Server.Host/Utils/PortAllocator.cs index 9b125103d0c..c2337135bc9 100644 --- a/src/Tgstation.Server.Host/Utils/PortAllocator.cs +++ b/src/Tgstation.Server.Host/Utils/PortAllocator.cs @@ -58,7 +58,7 @@ public PortAllocator( } /// - public async Task GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken) + public async ValueTask GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken) { logger.LogTrace("Port allocation >= {basePort} requested...", basePort); diff --git a/tests/Tgstation.Server.Host.Console.Tests/TestProgram.cs b/tests/Tgstation.Server.Host.Console.Tests/TestProgram.cs index 0fc337843c4..6276353b2af 100644 --- a/tests/Tgstation.Server.Host.Console.Tests/TestProgram.cs +++ b/tests/Tgstation.Server.Host.Console.Tests/TestProgram.cs @@ -17,7 +17,7 @@ public async Task TestProgramRuns() { var mockServer = new Mock(); var args = Array.Empty(); - mockServer.Setup(x => x.RunAsync(false, args, It.IsAny())).Returns(Task.FromResult(true)).Verifiable(); + mockServer.Setup(x => x.RunAsync(false, args, It.IsAny())).Returns(ValueTask.FromResult(true)).Verifiable(); var mockServerFactory = new Mock(); mockServerFactory.Setup(x => x.CreateWatchdog(It.IsNotNull(), It.IsNotNull())).Returns(mockServer.Object).Verifiable(); Program.WatchdogFactory = mockServerFactory.Object; diff --git a/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs b/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs index 7c5ae3bed2f..e1f604a5334 100644 --- a/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs +++ b/tests/Tgstation.Server.Host.Service.Tests/TestServerService.cs @@ -35,7 +35,7 @@ public void TestRun() var mockWatchdog = new Mock(); var args = Array.Empty(); CancellationToken cancellationToken = default; - Task signalCheckerTask = null; + ValueTask? signalCheckerTask = null; var childStarted = false; ISignalChecker signalChecker = null; @@ -47,7 +47,7 @@ public void TestRun() childStarted = true; return (123, Task.CompletedTask); }, cancellationToken); - }).Returns(Task.FromResult(true)).Verifiable(); + }).Returns(ValueTask.FromResult(true)).Verifiable(); var mockWatchdogFactory = new Mock(); mockWatchdogFactory.Setup(x => x.CreateWatchdog(It.IsNotNull(), It.IsNotNull())) @@ -67,7 +67,7 @@ public void TestRun() } mockWatchdogFactory.VerifyAll(); - Assert.IsTrue(signalCheckerTask.IsCompleted); + Assert.IsTrue(signalCheckerTask.Value.IsCompleted); } } } diff --git a/tests/Tgstation.Server.Host.Tests/IO/TestIOManager.cs b/tests/Tgstation.Server.Host.Tests/IO/TestIOManager.cs index f92ffaa04db..f8b7a9b7c92 100644 --- a/tests/Tgstation.Server.Host.Tests/IO/TestIOManager.cs +++ b/tests/Tgstation.Server.Host.Tests/IO/TestIOManager.cs @@ -88,28 +88,28 @@ await Assert.ThrowsExceptionAsync(() => ioManager.CopyDir null, tempPath2, throttle, - default)); + default).AsTask()); await Assert.ThrowsExceptionAsync(() => ioManager.CopyDirectory( null, null, tempPath1, null, throttle, - default)); + default).AsTask()); await Assert.ThrowsExceptionAsync(() => ioManager.CopyDirectory( null, null, null, null, throttle, - default)); + default).AsTask()); await Assert.ThrowsExceptionAsync(() => ioManager.CopyDirectory( null, null, tempPath1, tempPath2, -1, - default)); + default).AsTask()); } [TestMethod] diff --git a/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs b/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs index 3b9da3b2b3c..823036a10b3 100644 --- a/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs +++ b/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs @@ -104,10 +104,10 @@ public async Task TestWithUserStupidity() return $"{paths[0]}/{paths[1]}"; }).Verifiable(); mockIOManager.Setup(x => x.FileExists(It.IsNotNull(), It.IsAny())).Returns(Task.FromResult(true)).Verifiable(); - mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull(), It.IsAny())).Returns(Task.FromResult(Encoding.UTF8.GetBytes("less profane"))).Verifiable(); + mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull(), It.IsAny())).Returns(ValueTask.FromResult(Encoding.UTF8.GetBytes("less profane"))).Verifiable(); mockIOManager .Setup(x => x.WriteAllBytes(It.IsNotNull(), It.IsNotNull(), It.IsAny())) - .Returns(Task.CompletedTask) + .Returns(ValueTask.CompletedTask) .Verifiable(); var mockSuccessCommand = new Mock(); @@ -306,7 +306,7 @@ async Task RunWizard() await RunWizard(); //second run - mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull(), It.IsAny())).Returns(Task.FromResult(Encoding.UTF8.GetBytes(String.Empty))).Verifiable(); + mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull(), It.IsAny())).Returns(ValueTask.FromResult(Encoding.UTF8.GetBytes(String.Empty))).Verifiable(); await RunWizard(); //third run diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/TestSwarmProtocol.cs b/tests/Tgstation.Server.Host.Tests/Swarm/TestSwarmProtocol.cs index 5845fe177e7..2ae9c2e0ff4 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/TestSwarmProtocol.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/TestSwarmProtocol.cs @@ -10,6 +10,7 @@ using Moq; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Core; using Tgstation.Server.Host.IO; @@ -206,7 +207,7 @@ public async Task TestSimultaneousPrepareDifferentVersionsFailsNodeFirst() await TestSimultaneousPrepareDifferentVersionsFails(false); } - static async Task TestSimultaneousPrepareDifferentVersionsFails(bool prepControllerFirst) + static async ValueTask TestSimultaneousPrepareDifferentVersionsFails(bool prepControllerFirst) { await using var controller = GenNode(); await using var node1 = GenNode(controller); @@ -219,7 +220,7 @@ static async Task TestSimultaneousPrepareDifferentVersionsFails(bool prepControl Assert.AreEqual(SwarmRegistrationResult.Success, await controller.TryInit()); Assert.AreEqual(SwarmRegistrationResult.Success, await node1.TryInit()); - Task controllerPrepareTask = null, nodePrepareTask; + ValueTask controllerPrepareTask = ValueTask.FromResult(SwarmPrepareResult.SuccessProviderNotRequired), nodePrepareTask; if (prepControllerFirst) controllerPrepareTask = controller.Service.PrepareUpdate(updateFileStreamProvider, new Version(4, 3, 2), default); @@ -230,7 +231,7 @@ static async Task TestSimultaneousPrepareDifferentVersionsFails(bool prepControl await Task.Yield(); - await Task.WhenAll(controllerPrepareTask, nodePrepareTask); + await ValueTaskExtensions.WhenAll(controllerPrepareTask, nodePrepareTask); Task nodeCommitTask = null, controllerCommitTask = null; @@ -248,13 +249,13 @@ static async Task TestSimultaneousPrepareDifferentVersionsFails(bool prepControl if (controllerPrepped != SwarmPrepareResult.Failure) { Assert.AreEqual(SwarmPrepareResult.SuccessHoldProviderUntilCommit, controllerPrepped); - controllerCommitTask = controller.Service.CommitUpdate(default); + controllerCommitTask = controller.Service.CommitUpdate(default).AsTask(); } if (nodePrepped != SwarmPrepareResult.Failure) { Assert.AreEqual(SwarmPrepareResult.SuccessHoldProviderUntilCommit, nodePrepped); - nodeCommitTask = node1.Service.CommitUpdate(default); + nodeCommitTask = node1.Service.CommitUpdate(default).AsTask(); } await Task.Yield(); diff --git a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs index 31b39a83c2b..c2933183811 100644 --- a/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs +++ b/tests/Tgstation.Server.Host.Tests/Swarm/TestableSwarmNode.cs @@ -237,7 +237,7 @@ private async Task ShutdownService(CancellationToken cancellationToken) throw new TaskCanceledException(); }).Verifiable(); - Task Invoke() => Service.Initialize(default); + Task Invoke() => Service.Initialize(default).AsTask(); SwarmRegistrationResult? result; if (cancel) diff --git a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs index 066370977c2..a32b9e389c1 100644 --- a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs +++ b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs @@ -3,7 +3,6 @@ using Moq; using System; using System.Runtime.InteropServices; -using System.Threading.Tasks; using Tgstation.Server.Host.IO; @@ -26,12 +25,12 @@ public static void Init(TestContext _) } [TestMethod] - public async Task TestGetUsername() + public void TestGetUsername() { if (!new PlatformIdentifier().IsWindows) Assert.Inconclusive("This test is buggy on linux and not required"); - var username = await features.GetExecutingUsername(global::System.Diagnostics.Process.GetCurrentProcess(), default); + var username = features.GetExecutingUsername(global::System.Diagnostics.Process.GetCurrentProcess()); Assert.IsTrue(username.Contains(Environment.UserName), $"Exepcted a string containing \"{Environment.UserName}\", got \"{username}\""); } } diff --git a/tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs index 1008406cd78..56a879c98d0 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs @@ -11,6 +11,7 @@ using Tgstation.Server.Api.Models.Request; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; +using Tgstation.Server.Common.Extensions; using Tgstation.Server.Host.IO; namespace Tgstation.Server.Tests.Live.Instance @@ -92,11 +93,11 @@ await configurationClient.Write(new ConfigurationFileRequest await configurationClient.CreateDirectory(staticDir, cancellationToken); } - public Task SetupDMApiTests(CancellationToken cancellationToken) + public ValueTask SetupDMApiTests(CancellationToken cancellationToken) { // just use an I/O manager here var ioManager = new DefaultIOManager(); - return Task.WhenAll( + return ValueTaskExtensions.WhenAll( ioManager.CopyDirectory( Enumerable.Empty(), null, @@ -176,7 +177,7 @@ async Task SequencedApiTests(CancellationToken cancellationToken) public Task RunPreWatchdog(CancellationToken cancellationToken) => Task.WhenAll( SequencedApiTests(cancellationToken), - SetupDMApiTests(cancellationToken), + SetupDMApiTests(cancellationToken).AsTask(), TestPregeneratedFilesExist(cancellationToken)); } } diff --git a/tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs b/tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs index bb23bbdc631..53e0c43a517 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs @@ -43,7 +43,7 @@ public TestBridgeHandler(TaskCompletionSource tcs, ILogger lo this.accessIdentifier = accessIdentifier; } - public async Task ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) + public async ValueTask ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) { try { From b06310a379be05b990861846bd127ca3a59a439e Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 7 Oct 2023 17:58:01 -0400 Subject: [PATCH 24/33] Adjust Discord embed footer when updated --- .../Components/Chat/Providers/DiscordProvider.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index d9d41273e4a..354ef10ee1b 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -368,7 +368,7 @@ public override async Task>>> SendUpd var messageResponse = await channelsClient.CreateMessageAsync( new Snowflake(channelId), - "DM: Deployment in Progress...", + "DM: Deployment in progress...", embeds: new List { embed }, ct: cancellationToken); @@ -377,7 +377,7 @@ public override async Task>>> SendUpd return async (errorMessage, dreamMakerOutput) => { - var completionString = errorMessage == null ? "Succeeded" : "Failed"; + var completionString = errorMessage == null ? "Pending" : "Failed"; Embed CreateUpdatedEmbed(string message, Color color) => new Embed { @@ -426,7 +426,7 @@ public override async Task>>> SendUpd errorMessage, false)); - var updatedMessageText = $"DM: Deployment {completionString}!"; + var updatedMessageText = errorMessage == null ? $"DM: Deployment pending reboot..." : $"DM: Deployment failed!"; IMessage updatedMessage = null; async Task CreateUpdatedMessage() @@ -474,13 +474,20 @@ async Task CreateUpdatedMessage() return; if (active) + { + completionString = "Succeeded"; + updatedMessageText = $"DM: Deployment succeeded!"; embed = CreateUpdatedEmbed( "The deployment completed successfully and was applied to server.", Color.Green); + } else + { + completionString = "Inactive"; embed = CreateUpdatedEmbed( "This deployment has been superceeded by a new one.", Color.Gray); + } var editResponse = await channelsClient.EditMessageAsync( new Snowflake(channelId), From fbf8b9f5a39d7a8046b7b76913f14a6a461d3592 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sun, 8 Oct 2023 10:07:03 -0400 Subject: [PATCH 25/33] Update CONTRIBUTING.md Semver and ValueTask notes --- .github/CONTRIBUTING.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d8b62ead678..68ae14de2f3 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -121,6 +121,8 @@ DO: - Use CancellationTokens where possible - Throw appropriate ArgumentExceptions for public functions - Use nullable references approprately +- Prefer `ValueTask`s to `Task`s where possible. +- Return `Task` instead of `ValueTask` if all the callers would need to `.AsTask()` it. DON'T: @@ -128,7 +130,7 @@ DON'T: - Use the internal keyword - Use the static keyword on fields where avoidable - Use the public keyword where avoidable -- Handle Tasks in a synchronous fashion +- Handle `ValueTask`s/`Task`s in a synchronous fashion - Use static methods from built-in keywords i.e. Use `Boolean.TryParse` instead of `bool.TryParse` ### Formatting @@ -244,13 +246,15 @@ We use this attribute to ensure EFCore generated tables are not nullable for spe ## Versioning -The version format we use is 4.\.\. The first number never changes and TGS 1/2/3/4 are to be considered seperate products. The numbers that follow are the semver. The criteria for changing a version number is as follows +We follow [semantic versioning](https://semver.org) (Although TGS 1/2/3 are to be considered seperate products). The numbers that follow are the semver. The criteria for changing a version number is as follows +- Major: A change that requires direct host access to apply properly. Generally, these are updates to the dotnet runtime. - Minor: A feature addition to the core server functionality. - Patch: Patch changes. Patch changes should be committed to the `master` branch if possible. These will be automatically merged into the `dev` branch. -All other changes should be made directly to the `dev` branch. These will be merged to `master` on the next minor release cycle. +All minor changes should be made directly to the `dev` branch. These will be merged to `master` on the next minor release cycle. +Major changes should be committed to the `VX` branch created when the time for a major release comes around. We have several subcomponent APIs we ship with the core server that have their own versions. @@ -261,7 +265,7 @@ We have several subcomponent APIs we ship with the core server that have their o - Host Watchdog - Web Control Panel -These are represent as standard [semver](https://semver.org/)s and don't affect the core version. The only stipulation is major changes to the HTTP and DreamMaker APIs or the configuration must coincide with a minor core version bump. +These don't affect the core version. The only stipulation is major changes to the HTTP and DreamMaker APIs or the configuration must coincide with a minor core version bump. All versions are stored in the master file [build/Version.props](../build/Version.props). They are repeatedly defined in a few other places, but integration tests will make sure they are consistent. @@ -271,6 +275,7 @@ The NuGet package Tgstation.Server.Client is another part of the suite which sho - Consider Tgstation.Server.Client it's own product, perform major and minor bumps according to semver semantics including the Tgstation.Server.Api code (but not the version). - Tgstation.Server.Api is a bit tricky as breaking code changes may occur without affecting the actual HTTP contract. For this reason, the library itself is versioned separately from the API contract. +- Tgstation.Server.Common is also versioned independently. ## Triage, Deployment, and Releasing From 79d7d929fe7c1ae93cc47332c27062953cf636e5 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 13 Oct 2023 21:14:57 -0400 Subject: [PATCH 26/33] Nuget package updates --- build/TestCommon.props | 4 ++-- build/Version.props | 2 +- .../Tgstation.Server.Host.csproj | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build/TestCommon.props b/build/TestCommon.props index 4e1b3add13b..5ee30f11474 100644 --- a/build/TestCommon.props +++ b/build/TestCommon.props @@ -8,12 +8,12 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/build/Version.props b/build/Version.props index a9f9f2dd7c0..ae9b61b8d14 100644 --- a/build/Version.props +++ b/build/Version.props @@ -17,7 +17,7 @@ netstandard2.0 6 - https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.22/dotnet-hosting-6.0.22-win.exe + https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.23/dotnet-hosting-6.0.23-win.exe 10.11.5 https://ftp.osuosl.org/pub/mariadb//mariadb-10.11.5/winx64-packages/mariadb-10.11.5-winx64.msi diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index ea827e234e6..f2844ae82bc 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -75,19 +75,19 @@ - + - + - + - + runtime; build; native; contentfiles; analyzers; buildtransitive - + - + @@ -95,7 +95,7 @@ - + @@ -121,7 +121,7 @@ - + From 3740c4d89388ce3c0d62807a41cb0502941028e9 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 14 Oct 2023 14:02:14 -0400 Subject: [PATCH 27/33] Update webpanel version --- build/ControlPanelVersion.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/ControlPanelVersion.props b/build/ControlPanelVersion.props index 375980c5027..c2a4c37602f 100644 --- a/build/ControlPanelVersion.props +++ b/build/ControlPanelVersion.props @@ -1,6 +1,6 @@ - 4.25.2 + 4.25.5 From 65d9785c240cda3f124fa24725fb56d8f2bff614 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 20 Oct 2023 21:41:14 -0400 Subject: [PATCH 28/33] Fix merge build errors --- tests/Tgstation.Server.Tests/Live/TestLiveServer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index 358d20edb72..260a9c457d2 100644 --- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -1027,7 +1027,7 @@ await ioManager.CopyDirectory( if (postWriteHandler.NeedsPostWrite(src)) postWriteHandler.HandleWrite(dest); - return Task.CompletedTask; + return ValueTask.CompletedTask; }, ioManager.ConcatPath( localRepoPath, @@ -1080,7 +1080,7 @@ async ValueTask RunGitCommand(string args) jobWaitTask = jobsTest.WaitForJob(repoResponse.ActiveJob, 300, false, null, cancellationToken); } - await Task.WhenAll(jobWaitTask, ddUpdateTask, dmUpdateTask); + await Task.WhenAll(jobWaitTask, ddUpdateTask.AsTask(), dmUpdateTask.AsTask()); var depsBytesTask = ioManager.ReadAllBytes( ioManager.ConcatPath(repoPath, "dependencies.sh"), @@ -1093,7 +1093,7 @@ async ValueTask RunGitCommand(string args) if (postWriteHandler.NeedsPostWrite(src)) postWriteHandler.HandleWrite(dest); - return Task.CompletedTask; + return ValueTask.CompletedTask; }, ioManager.ConcatPath( repoPath, @@ -1120,7 +1120,7 @@ async ValueTask RunGitCommand(string args) var byondJobTask = jobsTest.WaitForJob(byondJob.InstallJob, 60, false, null, cancellationToken); - await Task.WhenAll(scriptsCopyTask, byondJobTask); + await Task.WhenAll(scriptsCopyTask.AsTask(), byondJobTask); var compileJob = await instanceClient.DreamMaker.Compile(cancellationToken); From 232aa679c2f50475c098a3cff25d36a340899e98 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 20 Oct 2023 19:46:39 -0400 Subject: [PATCH 29/33] Version bump client and common library versions --- build/Version.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/Version.props b/build/Version.props index ae9b61b8d14..b2f8d5265bd 100644 --- a/build/Version.props +++ b/build/Version.props @@ -6,9 +6,9 @@ 5.16.2 4.7.1 9.12.0 - 6.0.1 + 7.0.0 11.1.2 - 12.1.2 + 13.0.0 6.5.3 5.6.1 1.4.0 From 6d674a71c1d298b19292697bbf524d74f285f65e Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 20 Oct 2023 19:56:54 -0400 Subject: [PATCH 30/33] Add explicit dependency on common csproj to client --- src/Tgstation.Server.Client/Tgstation.Server.Client.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj index af89800112b..6868098fa69 100644 --- a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj +++ b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj @@ -11,6 +11,7 @@ + From 6ab9fc51fcd68b908eabd945d8695ad4e8c5f813 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 21 Oct 2023 00:16:36 -0400 Subject: [PATCH 31/33] Remove unnecessary `RequiredAttribute`s --- src/Tgstation.Server.Host/Models/ReattachInformationBase.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Tgstation.Server.Host/Models/ReattachInformationBase.cs b/src/Tgstation.Server.Host/Models/ReattachInformationBase.cs index 5cad9efbce2..241fae5141a 100644 --- a/src/Tgstation.Server.Host/Models/ReattachInformationBase.cs +++ b/src/Tgstation.Server.Host/Models/ReattachInformationBase.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel.DataAnnotations; using System.Globalization; using Tgstation.Server.Api.Models; @@ -31,13 +30,11 @@ public abstract class ReattachInformationBase : DMApiParameters /// /// The level DreamDaemon was launched with. /// - [Required] public DreamDaemonSecurity LaunchSecurityLevel { get; set; } /// /// The DreamDaemon was launched with. /// - [Required] public DreamDaemonVisibility LaunchVisibility { get; set; } /// From 42b09376d2d90f783452814333dc6c2bec08ef2a Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 21 Oct 2023 00:18:30 -0400 Subject: [PATCH 32/33] Fix documentation comment errors --- .../Components/Session/SessionControllerFactory.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index 939632524ab..cf0dea0468f 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -628,7 +628,8 @@ async Task LogDDOutput(IProcess process, string outputFilePath, bool cliSupporte /// /// The . /// The . - /// The if any. + /// The the server was launched with. + /// The the server was launched with. /// The value of . /// A new class. RuntimeInformation CreateRuntimeInformation( From 279671c7cbd8d2e5ea184e2461c42af14b2b11df Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 21 Oct 2023 03:49:28 -0400 Subject: [PATCH 33/33] Remove failing and badly conceived test --- tests/DMAPI/LongRunning/Test.dm | 20 ------ .../Live/Instance/WatchdogTest.cs | 66 ------------------- 2 files changed, 86 deletions(-) diff --git a/tests/DMAPI/LongRunning/Test.dm b/tests/DMAPI/LongRunning/Test.dm index d3515034ee8..a77c3377b5d 100644 --- a/tests/DMAPI/LongRunning/Test.dm +++ b/tests/DMAPI/LongRunning/Test.dm @@ -146,26 +146,6 @@ var/run_bridge_test kajigger_test = TRUE return "we love casting spells" - var/expected_path = data["vaporeon"] - if(expected_path) - var/command - if(world.system_type == MS_WINDOWS) - command = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy Bypass -Command \"if('[expected_path]' -ne $(Get-Location)){ (Get-Location).Path | Out-File \"fuck_up.txt\"; exit 1; }\"" - else - command = "if \[\[ \"[expected_path]\" != \"$(pwd)\" \]\]; then echo $(pwd) > fuck_up.txt; exit 1; fi" - - world.log << "shell: [command]" - var/exitCode = shell(command) - - if(isnull(exitCode) || exitCode != 0) - var/fuck_up_reason = "DIDN'T READ" - if(fexists("fuck_up.txt")) - fuck_up_reason = "COULDN'T READ" - fuck_up_reason = file2text("fuck_up.txt") - return "Dir check shell command failed with code [exitCode || "null"]: [fuck_up_reason]" - - return "is the most pokemon of all time" - TgsChatBroadcast(new /datum/tgs_message_content("Recieved non-tgs topic: `[T]`")) return "feck" diff --git a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs index bd1671e05e8..329fab6aa19 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs @@ -131,8 +131,6 @@ await Task.WhenAll( await RunLongRunningTestThenUpdate(cancellationToken); - await TestDDIsntResolvingSymlink(cancellationToken); - await RunLongRunningTestThenUpdateWithNewDme(cancellationToken); await RunLongRunningTestThenUpdateWithByondVersionSwitch(cancellationToken); @@ -152,70 +150,6 @@ await instanceClient.DreamDaemon.Update(new DreamDaemonRequest System.Console.WriteLine($"TEST: END WATCHDOG TESTS {instanceClient.Metadata.Name}"); } - async ValueTask TestDDIsntResolvingSymlink(CancellationToken cancellationToken) - { - System.Console.WriteLine("STARTING SYMLINK RESOLVE TEST"); - var deployTask = DeployTestDme("long_running_test_rooted", DreamDaemonSecurity.Trusted, true, cancellationToken); - - var previous = await instanceClient.DreamDaemon.Read(cancellationToken); - if (previous.SecurityLevel.Value != DreamDaemonSecurity.Trusted) - { - var updated = await instanceClient.DreamDaemon.Update(new DreamDaemonRequest - { - SecurityLevel = DreamDaemonSecurity.Trusted - }, cancellationToken); - - Assert.AreEqual(DreamDaemonSecurity.Trusted, updated.SecurityLevel); - } - - var startState = await deployTask; - - await WaitForJob(await StartDD(cancellationToken), 30, false, null, cancellationToken); - - var command = topicClient.SanitizeString( - Path.GetFullPath( - Path.Combine( - instanceClient.Metadata.Path, - "Game", - "Live"))); - command = $"vaporeon={command}"; - - var topicRequestResult = await topicClient.SendTopic( - IPAddress.Loopback, - command, - ddPort, - cancellationToken); - - Assert.IsNotNull(topicRequestResult); - Assert.AreEqual("is the most pokemon of all time", topicRequestResult.StringData); - - await DeployTestDme("long_running_test_rooted", DreamDaemonSecurity.Trusted, true, cancellationToken); - var newState = await TellWorldToReboot(cancellationToken); - - Assert.AreNotEqual(startState.ActiveCompileJob.Id, newState.ActiveCompileJob.Id); - topicRequestResult = await topicClient.SendTopic( - IPAddress.Loopback, - command, - ddPort, - cancellationToken); - - Assert.IsNotNull(topicRequestResult); - Assert.AreEqual("is the most pokemon of all time", topicRequestResult.StringData); - - await instanceClient.DreamDaemon.Shutdown(cancellationToken); - if (previous.SecurityLevel.Value != DreamDaemonSecurity.Trusted) - { - var updated = await instanceClient.DreamDaemon.Update(new DreamDaemonRequest - { - SecurityLevel = previous.SecurityLevel - }, cancellationToken); - - Assert.AreEqual(previous.SecurityLevel, updated.SecurityLevel); - } - - System.Console.WriteLine("END SYMLINK RESOLVE TEST"); - } - async Task InteropTestsForLongRunningDme(CancellationToken cancellationToken) { await StartAndLeaveRunning(cancellationToken);