mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-31 00:50:45 +01:00
Final ValueTask conversion
This commit is contained in:
@@ -31,7 +31,7 @@ namespace Tgstation.Server.Host.Console
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task CheckSignals(Func<string, (int, Task)> startChild, CancellationToken cancellationToken)
|
||||
public async ValueTask CheckSignals(Func<string, (int, Task)> startChild, CancellationToken cancellationToken)
|
||||
{
|
||||
var (childPid, _) = startChild?.Invoke(null) ?? throw new ArgumentNullException(nameof(startChild));
|
||||
var signalTcs = new TaskCompletionSource<Signum>();
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Tgstation.Server.Host.Service
|
||||
}
|
||||
|
||||
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 @@ namespace Tgstation.Server.Host.Service
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task RunConfigure(CancellationToken cancellationToken)
|
||||
async ValueTask RunConfigure(CancellationToken cancellationToken)
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(builder =>
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Tgstation.Server.Host.Service
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task CheckSignals(Func<string, (int, Task)> startChildAndGetPid, CancellationToken cancellationToken)
|
||||
public async ValueTask CheckSignals(Func<string, (int, Task)> startChildAndGetPid, CancellationToken cancellationToken)
|
||||
{
|
||||
await using (commandPipeServer = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable))
|
||||
await using (readyPipeServer = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable))
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
/// </summary>
|
||||
/// <param name="startChild">An <see cref="Func{TResult}"/> to start the main process. It accepts an optional additional command line argument as a paramter and returns it's <see cref="System.Diagnostics.Process.Id"/> and lifetime <see cref="Task"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task CheckSignals(Func<string, (int, Task)> startChild, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CheckSignals(Func<string, (int, Task)> startChild, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
/// <param name="runConfigure">If the <see cref="IWatchdog"/> should just run the host configuration wizard and exit.</param>
|
||||
/// <param name="args">The arguments for the <see cref="IWatchdog"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> if there were no errors, <see langword="false"/> otherwise.</returns>
|
||||
Task<bool> RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="true"/> if there were no errors, <see langword="false"/> otherwise.</returns>
|
||||
ValueTask<bool> RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
public sealed class NoopSignalChecker : ISignalChecker
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task CheckSignals(Func<string, (int, Task)> startChild, CancellationToken cancellationToken)
|
||||
public ValueTask CheckSignals(Func<string, (int, Task)> startChild, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(startChild);
|
||||
startChild(null);
|
||||
return Task.CompletedTask;
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
/// <inheritdoc />
|
||||
#pragma warning disable CA1502 // TODO: Decomplexify
|
||||
#pragma warning disable CA1506
|
||||
public async Task<bool> RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken)
|
||||
public async ValueTask<bool> RunAsync(bool runConfigure, string[] args, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogInformation("Host watchdog starting...");
|
||||
int currentProcessId;
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
public abstract string GetDreamDaemonName(Version version, out bool supportsCli, out bool supportsMapThreads);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask CleanCache(CancellationToken cancellationToken)
|
||||
public async Task CleanCache(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
/// Attempts to cleans the BYOND cache folder for the system.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CleanCache(CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task CleanCache(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task ChangeChannels(long connectionId, IEnumerable<Models.ChatChannel> newChannels, CancellationToken cancellationToken)
|
||||
public async ValueTask ChangeChannels(long connectionId, IEnumerable<Models.ChatChannel> newChannels, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(newChannels);
|
||||
|
||||
@@ -261,7 +261,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
AddMessageTask(task);
|
||||
|
||||
Task callbackTask;
|
||||
Func<bool, ValueTask> finalUpdateAction = null;
|
||||
Func<bool, Task> finalUpdateAction = null;
|
||||
async Task CallbackTask(string errorMessage, string dreamMakerOutput)
|
||||
{
|
||||
await task;
|
||||
@@ -423,10 +423,10 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task UpdateTrackingContexts(CancellationToken cancellationToken)
|
||||
public async ValueTask UpdateTrackingContexts(CancellationToken cancellationToken)
|
||||
{
|
||||
var logMessageSent = 0;
|
||||
async Task UpdateTrackingContext(IChatTrackingContext channelSink, IEnumerable<ChannelRepresentation> channels)
|
||||
@@ -589,8 +589,8 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <param name="connectionId">The <see cref="Api.Models.EntityId.Id"/> of the <see cref="IProvider"/> to delete.</param>
|
||||
/// <param name="removeProvider">If the provider should be removed from <see cref="providers"/> and <see cref="trackingContexts"/> should be update.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IProvider"/> being removed if it exists, <see langword="null"/> otherwise.</returns>
|
||||
async Task<IProvider> RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="IProvider"/> being removed if it exists, <see langword="null"/> otherwise.</returns>
|
||||
async ValueTask<IProvider> RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("RemoveProviderChannels {connectionId}...", connectionId);
|
||||
IProvider provider;
|
||||
@@ -936,7 +936,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
logger.LogTrace("Starting processing loop...");
|
||||
var messageTasks = new Dictionary<IProvider, Task<Message>>();
|
||||
Task activeProcessingTask = Task.CompletedTask;
|
||||
ValueTask activeProcessingTask = ValueTask.CompletedTask;
|
||||
try
|
||||
{
|
||||
Task updatedTask = null;
|
||||
@@ -956,7 +956,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
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))
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// </summary>
|
||||
/// <param name="newSettings">The new <see cref="Models.ChatBot"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation. Will complete immediately if the <see cref="ChatBotSettings.Enabled"/> property of <paramref name="newSettings"/> is <see langword="false"/>.</returns>
|
||||
Task ChangeSettings(Models.ChatBot newSettings, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation. Will complete immediately if the <see cref="ChatBotSettings.Enabled"/> property of <paramref name="newSettings"/> is <see langword="false"/>.</returns>
|
||||
ValueTask ChangeSettings(Models.ChatBot newSettings, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects and deletes a given connection.
|
||||
@@ -41,8 +41,8 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <param name="connectionId">The <see cref="Api.Models.EntityId.Id"/> of the connection.</param>
|
||||
/// <param name="newChannels">An <see cref="IEnumerable{T}"/> of the new list of <see cref="Models.ChatChannel"/>s.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task ChangeChannels(long connectionId, IEnumerable<Models.ChatChannel> newChannels, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask ChangeChannels(long connectionId, IEnumerable<Models.ChatChannel> newChannels, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Queue a chat <paramref name="message"/> to a given set of <paramref name="channelIds"/>.
|
||||
@@ -85,7 +85,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// Force an update with the active channels on all active <see cref="IChatTrackingContext"/>s.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task UpdateTrackingContexts(CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask UpdateTrackingContexts(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
var embeds = ConvertEmbed(message.Embed);
|
||||
|
||||
var channelsClient = serviceProvider.GetRequiredService<IDiscordRestChannelAPI>();
|
||||
async Task SendToChannel(Snowflake channelId)
|
||||
async ValueTask SendToChannel(Snowflake channelId)
|
||||
{
|
||||
var result = await channelsClient.CreateMessageAsync(
|
||||
channelId,
|
||||
@@ -312,7 +312,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
var updatedMessageText = $"DM: Deployment {completionString}!";
|
||||
|
||||
IMessage updatedMessage = null;
|
||||
async Task CreateUpdatedMessage()
|
||||
async ValueTask CreateUpdatedMessage()
|
||||
{
|
||||
var createUpdatedMessageResponse = await channelsClient.CreateMessageAsync(
|
||||
new Snowflake(channelId),
|
||||
|
||||
@@ -39,12 +39,12 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
void InitialMappingComplete();
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="ValueTask{TResult}"/> resulting in the next <see cref="Message"/> the <see cref="IProvider"/> recieves or <see langword="null"/> on a disconnect.
|
||||
/// Get a <see cref="Task{TResult}"/> resulting in the next <see cref="Message"/> the <see cref="IProvider"/> recieves or <see langword="null"/> on a disconnect.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the next available <see cref="Message"/> or <see langword="null"/> if the <see cref="IProvider"/> needed to reconnect.</returns>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the next available <see cref="Message"/> or <see langword="null"/> if the <see cref="IProvider"/> needed to reconnect.</returns>
|
||||
/// <remarks>Note that private messages will come in the form of <see cref="ChannelRepresentation"/>s not returned in <see cref="MapChannels(IEnumerable{ChatChannel}, CancellationToken)"/>.</remarks>
|
||||
ValueTask<Message> NextMessage(CancellationToken cancellationToken);
|
||||
Task<Message> NextMessage(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gracefully disconnects the provider. Permanently stops the reconnection timer.
|
||||
|
||||
@@ -595,8 +595,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
/// Run SASL authentication on <see cref="client"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task SaslAuthenticate(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
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 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
/// Attempt to disconnect from IRC immediately.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task HardDisconnect(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask HardDisconnect(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<Message> NextMessage(CancellationToken cancellationToken)
|
||||
public async Task<Message> NextMessage(CancellationToken cancellationToken)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@@ -171,7 +171,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
{
|
||||
stopOldTimerTask = StopReconnectionTimer();
|
||||
reconnectCts = new CancellationTokenSource();
|
||||
reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token).AsTask();
|
||||
reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token);
|
||||
}
|
||||
|
||||
return stopOldTimerTask;
|
||||
@@ -260,8 +260,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
/// <param name="reconnectInterval">The amount of minutes to wait between reconnection attempts.</param>
|
||||
/// <param name="connectNow">If a connection attempt should be immediately made.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
||||
@@ -422,8 +422,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// </summary>
|
||||
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> to retrieve previous deployment <see cref="Job"/>s from.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the average <see cref="TimeSpan"/> of the 10 previous deployments or <see langword="null"/> if there are none.</returns>
|
||||
async Task<TimeSpan?> CalculateExpectedDeploymentTime(IDatabaseContext databaseContext, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the average <see cref="TimeSpan"/> of the 10 previous deployments or <see langword="null"/> if there are none.</returns>
|
||||
async ValueTask<TimeSpan?> CalculateExpectedDeploymentTime(IDatabaseContext databaseContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var previousCompileJobs = await databaseContext
|
||||
.CompileJobs
|
||||
@@ -462,8 +462,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="estimatedDuration">The optional estimated <see cref="TimeSpan"/> of the compilation.</param>
|
||||
/// <param name="localCommitExistsOnRemote">Whether or not the <paramref name="repository"/>'s current commit exists on the remote repository.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the completed <see cref="CompileJob"/>.</returns>
|
||||
async Task<Models.CompileJob> Compile(
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the completed <see cref="CompileJob"/>.</returns>
|
||||
async ValueTask<Models.CompileJob> Compile(
|
||||
Models.RevisionInformation revisionInformation,
|
||||
Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
|
||||
DreamDaemonLaunchParameters launchParameters,
|
||||
@@ -557,8 +557,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="repository">The <see cref="IRepository"/> to use.</param>
|
||||
/// <param name="remoteDeploymentManager">The <see cref="IRemoteDeploymentManager"/> to use.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task RunCompileJob(
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask RunCompileJob(
|
||||
JobProgressReporter progressReporter,
|
||||
Models.CompileJob job,
|
||||
Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
|
||||
@@ -711,8 +711,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="progressReporter">The <see cref="JobProgressReporter"/> to report progress of the operation.</param>
|
||||
/// <param name="estimatedDuration">A <see cref="TimeSpan"/> representing the duration to give progress over if any.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task ProgressTask(JobProgressReporter progressReporter, TimeSpan? estimatedDuration, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask ProgressTask(JobProgressReporter progressReporter, TimeSpan? estimatedDuration, CancellationToken cancellationToken)
|
||||
{
|
||||
double? lastReport = estimatedDuration.HasValue ? 0 : null;
|
||||
progressReporter.ReportProgress(lastReport);
|
||||
@@ -774,8 +774,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="requireValidate">If the API validation is required to complete the deployment.</param>
|
||||
/// <param name="logOutput">If output should be logged to the DreamDaemon Diagnostics folder.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task VerifyApi(
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask VerifyApi(
|
||||
uint timeout,
|
||||
DreamDaemonSecurity securityLevel,
|
||||
Models.CompileJob job,
|
||||
@@ -856,8 +856,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="dreamMakerPath">The path to the DreamMaker executable.</param>
|
||||
/// <param name="job">The <see cref="CompileJob"/> for the operation.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task<int> RunDreamMaker(string dreamMakerPath, Models.CompileJob job, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask<int> RunDreamMaker(string dreamMakerPath, Models.CompileJob job, CancellationToken cancellationToken)
|
||||
{
|
||||
await using var dm = processExecutor.LaunchProcess(
|
||||
dreamMakerPath,
|
||||
@@ -887,8 +887,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// </summary>
|
||||
/// <param name="job">The <see cref="CompileJob"/> for the operation.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task ModifyDme(Models.CompileJob job, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask ModifyDme(Models.CompileJob job, CancellationToken cancellationToken)
|
||||
{
|
||||
var dmeFileName = String.Join('.', job.DmeName, DmeExtension);
|
||||
var dmePath = ioManager.ConcatPath(job.DirectoryName.ToString(), dmeFileName);
|
||||
|
||||
@@ -74,8 +74,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// Make the <see cref="SwappableDmbProvider"/> active by replacing the live link with our <see cref="CompileJob"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
public async Task MakeActive(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
public async ValueTask MakeActive(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Interlocked.Exchange(ref swapped, 1) != 0)
|
||||
throw new InvalidOperationException("Already swapped!");
|
||||
|
||||
@@ -317,7 +317,7 @@ namespace Tgstation.Server.Host.Components
|
||||
var hasDbChanges = false;
|
||||
RevisionInformation currentRevInfo = null;
|
||||
Models.Instance attachedInstance = null;
|
||||
async Task UpdateRevInfo(string currentHead, bool onOrigin, IEnumerable<TestMerge> updatedTestMerges)
|
||||
async ValueTask UpdateRevInfo(string currentHead, bool onOrigin, IEnumerable<TestMerge> updatedTestMerges)
|
||||
{
|
||||
if (currentRevInfo == null)
|
||||
{
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace Tgstation.Server.Host.Components
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
CheckSystemCompatibility();
|
||||
return byondInstaller.CleanCache(cancellationToken).AsTask();
|
||||
return byondInstaller.CleanCache(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -460,7 +460,7 @@ namespace Tgstation.Server.Host.Components
|
||||
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 @@ namespace Tgstation.Server.Host.Components
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ namespace Tgstation.Server.Host.Components
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
public async ValueTask<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(parameters);
|
||||
|
||||
@@ -650,8 +650,8 @@ namespace Tgstation.Server.Host.Components
|
||||
/// Initializes the connection to the TGS swarm.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task InitializeSwarm(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask InitializeSwarm(CancellationToken cancellationToken)
|
||||
{
|
||||
SwarmRegistrationResult registrationResult;
|
||||
do
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
|
||||
/// </summary>
|
||||
/// <param name="parameters">The <see cref="BridgeParameters"/> to handle.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="BridgeResponse"/> for the request or <see langword="null"/> if the request could not be dispatched.</returns>
|
||||
Task<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="BridgeResponse"/> for the request or <see langword="null"/> if the request could not be dispatched.</returns>
|
||||
ValueTask<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,9 +63,9 @@ namespace Tgstation.Server.Host.Components.Interop
|
||||
/// <param name="chunkErrorCallback">The callback that generates a <typeparamref name="TResponse"/> for a given error.</param>
|
||||
/// <param name="chunk">The <see cref="ChunkData"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <typeparamref name="TResponse"/> for the chunked request.</returns>
|
||||
protected async Task<TResponse> ProcessChunk<TCommnication, TResponse>(
|
||||
Func<TCommnication, CancellationToken, Task<TResponse>> completionCallback,
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <typeparamref name="TResponse"/> for the chunked request.</returns>
|
||||
protected async ValueTask<TResponse> ProcessChunk<TCommnication, TResponse>(
|
||||
Func<TCommnication, CancellationToken, ValueTask<TResponse>> completionCallback,
|
||||
Func<string, TResponse> chunkErrorCallback,
|
||||
ChunkData chunk,
|
||||
CancellationToken cancellationToken)
|
||||
|
||||
@@ -535,7 +535,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (postWriteHandler.NeedsPostWrite(src))
|
||||
postWriteHandler.HandleWrite(dest);
|
||||
|
||||
return Task.CompletedTask;
|
||||
return ValueTask.CompletedTask;
|
||||
},
|
||||
ioMananger.ResolvePath(),
|
||||
path,
|
||||
@@ -992,8 +992,8 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// <param name="password">The password for the <see cref="credentialsProvider"/>.</param>
|
||||
/// <param name="deploymentPipeline">If any events created should be marked as part of the deployment pipeline.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task UpdateSubmodules(
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask UpdateSubmodules(
|
||||
JobProgressReporter progressReporter,
|
||||
string username,
|
||||
string password,
|
||||
|
||||
@@ -362,7 +362,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
public async ValueTask<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(parameters);
|
||||
|
||||
@@ -439,7 +439,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
(completedResponse, cancellationToken) =>
|
||||
{
|
||||
fullResponse = completedResponse;
|
||||
return Task.FromResult<ChunkedTopicParameters>(null);
|
||||
return ValueTask.FromResult<ChunkedTopicParameters>(null);
|
||||
},
|
||||
error =>
|
||||
{
|
||||
@@ -574,7 +574,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task CreateDump(string outputFile, CancellationToken cancellationToken) => process.CreateDump(outputFile, cancellationToken);
|
||||
public ValueTask CreateDump(string outputFile, CancellationToken cancellationToken) => process.CreateDump(outputFile, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Task{TResult}"/> for <see cref="LaunchResult"/>.
|
||||
@@ -660,8 +660,8 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
/// </summary>
|
||||
/// <param name="parameters">The <see cref="BridgeParameters"/> to handle.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="BridgeResponse"/> for the request or <see langword="null"/> if the request could not be dispatched.</returns>
|
||||
async Task<BridgeResponse> ProcessBridgeCommand(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="BridgeResponse"/> for the request or <see langword="null"/> if the request could not be dispatched.</returns>
|
||||
async ValueTask<BridgeResponse> ProcessBridgeCommand(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
var response = new BridgeResponse();
|
||||
switch (parameters.CommandType)
|
||||
@@ -828,8 +828,8 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
/// </summary>
|
||||
/// <param name="parameters">The <see cref="TopicParameters"/> to send.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="CombinedTopicResponse"/> of the topic request.</returns>
|
||||
async Task<CombinedTopicResponse> SendTopicRequest(TopicParameters parameters, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="CombinedTopicResponse"/> of the topic request.</returns>
|
||||
async ValueTask<CombinedTopicResponse> SendTopicRequest(TopicParameters parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
parameters.AccessIdentifier = ReattachInformation.AccessIdentifier;
|
||||
|
||||
@@ -971,8 +971,8 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
/// <param name="queryString">The sanitized topic query string to send.</param>
|
||||
/// <param name="priority">If this is a priority message. If so, the topic will make 5 attempts to send unless BYOND reboots or exits.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="CombinedTopicResponse"/> of the topic request.</returns>
|
||||
async Task<CombinedTopicResponse> SendRawTopic(string queryString, bool priority, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="CombinedTopicResponse"/> of the topic request.</returns>
|
||||
async ValueTask<CombinedTopicResponse> SendRawTopic(string queryString, bool priority, CancellationToken cancellationToken)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
|
||||
@@ -239,6 +239,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
#pragma warning disable CA1506 // TODO: Decomplexify
|
||||
public async ValueTask<ISessionController> LaunchNew(
|
||||
IDmbProvider dmbProvider,
|
||||
IByondExecutableLock currentByondLock,
|
||||
@@ -283,7 +284,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
dmbProvider.CompileJob.Id);
|
||||
|
||||
PortBindTest(launchParameters.Port.Value);
|
||||
await CheckPagerIsNotRunning(cancellationToken);
|
||||
await CheckPagerIsNotRunning();
|
||||
|
||||
string outputFilePath = null;
|
||||
var preserveLogFile = true;
|
||||
@@ -393,6 +394,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1506
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<ISessionController> Reattach(
|
||||
@@ -647,9 +649,8 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
/// <summary>
|
||||
/// Make sure the BYOND pager is not running.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task CheckPagerIsNotRunning(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask CheckPagerIsNotRunning()
|
||||
{
|
||||
if (!platformIdentifier.IsWindows)
|
||||
return;
|
||||
@@ -658,12 +659,12 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
if (otherProcess == null)
|
||||
return;
|
||||
|
||||
var otherUsernameTask = otherProcess.GetExecutingUsername(cancellationToken);
|
||||
await using var ourProcess = processExecutor.GetCurrentProcess();
|
||||
var ourUserName = await ourProcess.GetExecutingUsername(cancellationToken);
|
||||
var otherUserName = await otherUsernameTask;
|
||||
var otherUsername = otherProcess.GetExecutingUsername();
|
||||
|
||||
if (otherUserName.Equals(ourUserName, StringComparison.Ordinal))
|
||||
await using var ourProcess = processExecutor.GetCurrentProcess();
|
||||
var ourUsername = ourProcess.GetExecutingUsername();
|
||||
|
||||
if (otherUsername.Equals(ourUsername, StringComparison.Ordinal))
|
||||
throw new JobException(ErrorCode.DeploymentPagerRunning);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
Models.ReattachInformation result = null;
|
||||
TimeSpan? topicTimeout = null;
|
||||
|
||||
async Task KillProcess(Models.ReattachInformation reattachInfo)
|
||||
async ValueTask KillProcess(Models.ReattachInformation reattachInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -219,7 +219,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
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 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
/// <inheritdoc />
|
||||
public async ValueTask SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken)
|
||||
{
|
||||
async Task<IReadOnlyList<string>> GetIgnoreFiles()
|
||||
{
|
||||
var ignoreFileBytes = await ioManager.ReadAllBytes(StaticIgnorePath(), cancellationToken);
|
||||
var ignoreFileText = Encoding.UTF8.GetString(ignoreFileBytes);
|
||||
|
||||
var results = new List<string> { 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<string> ignoreFiles;
|
||||
List<string> ignoreFiles;
|
||||
|
||||
async ValueTask SymlinkBase(bool files)
|
||||
{
|
||||
@@ -458,7 +439,20 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
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<string> { 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 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task EnsureDirectories(CancellationToken cancellationToken)
|
||||
Task EnsureDirectories(CancellationToken cancellationToken)
|
||||
{
|
||||
async Task ValidateStaticFolder()
|
||||
{
|
||||
@@ -721,7 +715,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
return;
|
||||
|
||||
await ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken);
|
||||
await Task.WhenAll(
|
||||
await ValueTaskExtensions.WhenAll(
|
||||
ioManager.WriteAllBytes(
|
||||
ioManager.ConcatPath(
|
||||
CodeModificationsSubdirectory,
|
||||
@@ -736,7 +730,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
cancellationToken));
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
return Task.WhenAll(
|
||||
ValidateCodeModsFolder(),
|
||||
ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken),
|
||||
ValidateStaticFolder());
|
||||
|
||||
@@ -395,8 +395,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StopAsync(CancellationToken cancellationToken) =>
|
||||
TerminateNoLock(false, !releaseServers, cancellationToken);
|
||||
public async Task StopAsync(CancellationToken cancellationToken) =>
|
||||
await TerminateNoLock(false, !releaseServers, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask Terminate(bool graceful, CancellationToken cancellationToken)
|
||||
@@ -1002,8 +1002,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="graceful">If <see langword="true"/> the termination will be delayed until a reboot is detected in the active server's DMAPI and this function will return immediately.</param>
|
||||
/// <param name="announce">If <see langword="true"/> the termination will be announced using <see cref="Chat"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task TerminateNoLock(bool graceful, bool announce, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask TerminateNoLock(bool graceful, bool announce, CancellationToken cancellationToken)
|
||||
{
|
||||
if (Status == WatchdogStatus.Offline)
|
||||
return;
|
||||
|
||||
@@ -331,8 +331,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// Create the initial link to the live game directory using <see cref="ActiveSwappable"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task InitialLink(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask InitialLink(CancellationToken cancellationToken)
|
||||
{
|
||||
Logger.LogTrace("Symlinking compile job...");
|
||||
return ActiveSwappable.MakeActive(cancellationToken);
|
||||
|
||||
@@ -95,14 +95,14 @@ namespace Tgstation.Server.Host.IO
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
public Task EnsureBuffered(CancellationToken cancellationToken) => GetResultInternal(cancellationToken);
|
||||
public Task EnsureBuffered(CancellationToken cancellationToken) => GetResultInternal(cancellationToken).AsTask();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the shared <see cref="MemoryStream"/> and its <see cref="Stream.Length"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see cref="buffer"/> and its <see cref="Stream.Length"/>.</returns>
|
||||
async Task<(MemoryStream, long)> GetResultInternal(CancellationToken cancellationToken)
|
||||
async ValueTask<(MemoryStream, long)> GetResultInternal(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!buffered)
|
||||
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken))
|
||||
|
||||
@@ -68,9 +68,9 @@ namespace Tgstation.Server.Host.IO
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task CopyDirectory(
|
||||
public async ValueTask CopyDirectory(
|
||||
IEnumerable<string> ignore,
|
||||
Func<string, string, Task> postCopyCallback,
|
||||
Func<string, string, ValueTask> postCopyCallback,
|
||||
string src,
|
||||
string dest,
|
||||
int? taskThrottle,
|
||||
@@ -93,7 +93,7 @@ namespace Tgstation.Server.Host.IO
|
||||
public string ConcatPath(params string[] paths) => Path.Combine(paths);
|
||||
|
||||
/// <inheritdoc />
|
||||
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 @@ namespace Tgstation.Server.Host.IO
|
||||
TaskScheduler.Current);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<byte[]> ReadAllBytes(string path, CancellationToken cancellationToken)
|
||||
public async ValueTask<byte[]> ReadAllBytes(string path, CancellationToken cancellationToken)
|
||||
{
|
||||
path = ResolvePath(path);
|
||||
await using var file = new FileStream(
|
||||
@@ -220,7 +220,7 @@ namespace Tgstation.Server.Host.IO
|
||||
public virtual string ResolvePath(string path) => Path.GetFullPath(path ?? throw new ArgumentNullException(nameof(path)));
|
||||
|
||||
/// <inheritdoc />
|
||||
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 @@ namespace Tgstation.Server.Host.IO
|
||||
string src,
|
||||
string dest,
|
||||
IEnumerable<string> ignore,
|
||||
Func<string, string, Task> postCopyCallback,
|
||||
Func<string, string, ValueTask> postCopyCallback,
|
||||
SemaphoreSlim semaphore,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
@@ -54,10 +54,10 @@ namespace Tgstation.Server.Host.IO
|
||||
/// <param name="dest">The destination directory path.</param>
|
||||
/// <param name="taskThrottle">The optional maximum number of simultaneous tasks allowed to execute.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task CopyDirectory(
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CopyDirectory(
|
||||
IEnumerable<string> ignore,
|
||||
Func<string, string, Task> postCopyCallback,
|
||||
Func<string, string, ValueTask> postCopyCallback,
|
||||
string src,
|
||||
string dest,
|
||||
int? taskThrottle,
|
||||
@@ -84,8 +84,8 @@ namespace Tgstation.Server.Host.IO
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file to read.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> that results in the contents of a file at <paramref name="path"/>.</returns>
|
||||
Task<byte[]> ReadAllBytes(string path, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> that results in the contents of a file at <paramref name="path"/>.</returns>
|
||||
ValueTask<byte[]> ReadAllBytes(string path, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns directory names in a given <paramref name="path"/>.
|
||||
@@ -116,8 +116,8 @@ namespace Tgstation.Server.Host.IO
|
||||
/// <param name="path">The path of the file to write.</param>
|
||||
/// <param name="contents">The contents of the file.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Copy a file from <paramref name="src"/> to <paramref name="dest"/>.
|
||||
@@ -125,8 +125,8 @@ namespace Tgstation.Server.Host.IO
|
||||
/// <param name="src">The source file to copy.</param>
|
||||
/// <param name="dest">The destination path.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task CopyFile(string src, string dest, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CopyFile(string src, string dest, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directory portion of a given <paramref name="path"/>.
|
||||
|
||||
@@ -137,8 +137,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// <param name="question">The question <see cref="string"/>.</param>
|
||||
/// <param name="defaultResponse">The optional default response if the user doesn't enter anything.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> resulting in <see langword="true"/> if the user replied yes, <see langword="false"/> otherwise.</returns>
|
||||
async Task<bool> PromptYesNo(string question, bool? defaultResponse, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> resulting in <see langword="true"/> if the user replied yes, <see langword="false"/> otherwise.</returns>
|
||||
async ValueTask<bool> PromptYesNo(string question, bool? defaultResponse, CancellationToken cancellationToken)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -167,8 +167,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to enter the port to host TGS on.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> resulting in the hosting port, or <see langword="null"/> to use the default.</returns>
|
||||
async Task<ushort?> PromptForHostingPort(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> resulting in the hosting port, or <see langword="null"/> to use the default.</returns>
|
||||
async ValueTask<ushort?> 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 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// <param name="databaseName">The database name (or path in the case of a <see cref="DatabaseType.Sqlite"/> database).</param>
|
||||
/// <param name="dbExists">Whether or not the database exists.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task TestDatabaseConnection(
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask TestDatabaseConnection(
|
||||
DbConnection testConnection,
|
||||
DatabaseConfiguration databaseConfiguration,
|
||||
string databaseName,
|
||||
@@ -290,8 +290,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// </summary>
|
||||
/// <param name="databaseName">The path to the potential SQLite database file.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the SQLite database path to store in the configuration.</returns>
|
||||
async Task<string> ValidateNonExistantSqliteDBName(string databaseName, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the SQLite database path to store in the configuration.</returns>
|
||||
async ValueTask<string> ValidateNonExistantSqliteDBName(string databaseName, CancellationToken cancellationToken)
|
||||
{
|
||||
var dbPathIsRooted = Path.IsPathRooted(databaseName);
|
||||
var resolvedPath = ioManager.ResolvePath(
|
||||
@@ -343,8 +343,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// </summary>
|
||||
/// <param name="firstTime">If this is the user's first time here.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the input <see cref="DatabaseType"/>.</returns>
|
||||
async Task<DatabaseType> PromptDatabaseType(bool firstTime, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the input <see cref="DatabaseType"/>.</returns>
|
||||
async ValueTask<DatabaseType> PromptDatabaseType(bool firstTime, CancellationToken cancellationToken)
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
@@ -392,9 +392,9 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to create a <see cref="DatabaseConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="DatabaseConfiguration"/>.</returns>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the new <see cref="DatabaseConfiguration"/>.</returns>
|
||||
#pragma warning disable CA1502 // TODO: Decomplexify
|
||||
async Task<DatabaseConfiguration> ConfigureDatabase(CancellationToken cancellationToken)
|
||||
async ValueTask<DatabaseConfiguration> ConfigureDatabase(CancellationToken cancellationToken)
|
||||
{
|
||||
bool firstTime = true;
|
||||
do
|
||||
@@ -656,8 +656,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to create a <see cref="GeneralConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="GeneralConfiguration"/>.</returns>
|
||||
async Task<GeneralConfiguration> ConfigureGeneral(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the new <see cref="GeneralConfiguration"/>.</returns>
|
||||
async ValueTask<GeneralConfiguration> ConfigureGeneral(CancellationToken cancellationToken)
|
||||
{
|
||||
var newGeneralConfiguration = new GeneralConfiguration
|
||||
{
|
||||
@@ -714,8 +714,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to create a <see cref="FileLoggingConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="FileLoggingConfiguration"/>.</returns>
|
||||
async Task<FileLoggingConfiguration> ConfigureLogging(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the new <see cref="FileLoggingConfiguration"/>.</returns>
|
||||
async ValueTask<FileLoggingConfiguration> ConfigureLogging(CancellationToken cancellationToken)
|
||||
{
|
||||
var fileLoggingConfiguration = new FileLoggingConfiguration();
|
||||
await console.WriteAsync(null, true, cancellationToken);
|
||||
@@ -771,7 +771,7 @@ namespace Tgstation.Server.Host.Setup
|
||||
}
|
||||
while (true);
|
||||
|
||||
async Task<LogLevel?> PromptLogLevel(string question)
|
||||
async ValueTask<LogLevel?> PromptLogLevel(string question)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -799,8 +799,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to create a <see cref="ElasticsearchConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="ElasticsearchConfiguration"/>.</returns>
|
||||
async Task<ElasticsearchConfiguration> ConfigureElasticsearch(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the new <see cref="ElasticsearchConfiguration"/>.</returns>
|
||||
async ValueTask<ElasticsearchConfiguration> ConfigureElasticsearch(CancellationToken cancellationToken)
|
||||
{
|
||||
var elasticsearchConfiguration = new ElasticsearchConfiguration();
|
||||
await console.WriteAsync(null, true, cancellationToken);
|
||||
@@ -851,8 +851,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to create a <see cref="ControlPanelConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="ControlPanelConfiguration"/>.</returns>
|
||||
async Task<ControlPanelConfiguration> ConfigureControlPanel(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the new <see cref="ControlPanelConfiguration"/>.</returns>
|
||||
async ValueTask<ControlPanelConfiguration> ConfigureControlPanel(CancellationToken cancellationToken)
|
||||
{
|
||||
var config = new ControlPanelConfiguration
|
||||
{
|
||||
@@ -881,8 +881,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Prompts the user to create a <see cref="SwarmConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="SwarmConfiguration"/>.</returns>
|
||||
async Task<SwarmConfiguration> ConfigureSwarm(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the new <see cref="SwarmConfiguration"/>.</returns>
|
||||
async ValueTask<SwarmConfiguration> ConfigureSwarm(CancellationToken cancellationToken)
|
||||
{
|
||||
var enable = await PromptYesNo("Enable swarm mode?", false, cancellationToken);
|
||||
if (!enable)
|
||||
@@ -896,7 +896,7 @@ namespace Tgstation.Server.Host.Setup
|
||||
}
|
||||
while (String.IsNullOrWhiteSpace(identifer));
|
||||
|
||||
async Task<Uri> ParseAddress(string question)
|
||||
async ValueTask<Uri> ParseAddress(string question)
|
||||
{
|
||||
var first = true;
|
||||
Uri address;
|
||||
@@ -956,8 +956,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// <param name="controlPanelConfiguration">The <see cref="ControlPanelConfiguration"/> to save.</param>
|
||||
/// <param name="swarmConfiguration">The <see cref="SwarmConfiguration"/> to save.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task SaveConfiguration(
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask SaveConfiguration(
|
||||
string userConfigFileName,
|
||||
ushort? hostingPort,
|
||||
DatabaseConfiguration databaseConfiguration,
|
||||
@@ -1027,8 +1027,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// </summary>
|
||||
/// <param name="userConfigFileName">The path to the settings json to build.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task RunWizard(string userConfigFileName, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask RunWizard(string userConfigFileName, CancellationToken cancellationToken)
|
||||
{
|
||||
// welcome message
|
||||
await console.WriteAsync($"Welcome to {Constants.CanonicalPackageName}!", true, cancellationToken);
|
||||
@@ -1067,8 +1067,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
/// Check if it should and run the <see cref="SetupWizard"/> if necessary.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task CheckRunWizard(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask CheckRunWizard(CancellationToken cancellationToken)
|
||||
{
|
||||
var setupWizardMode = generalConfiguration.SetupWizardMode;
|
||||
if (setupWizardMode == SetupWizardMode.Never)
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// </summary>
|
||||
/// <param name="updateRequest">The <see cref="SwarmUpdateRequest"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> if the node is able to update, <see langword="false"/> otherwise.</returns>
|
||||
Task<bool> PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="true"/> if the node is able to update, <see langword="false"/> otherwise.</returns>
|
||||
ValueTask<bool> PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Validate a given <paramref name="registrationId"/>.
|
||||
@@ -39,23 +39,23 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <param name="node">The <see cref="SwarmServerResponse"/> that is registering.</param>
|
||||
/// <param name="registrationId">The registration <see cref="Guid"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> if the registration was successful, <see langword="false"/> otherwise.</returns>
|
||||
Task<bool> RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="true"/> if the registration was successful, <see langword="false"/> otherwise.</returns>
|
||||
ValueTask<bool> RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to unregister a node with a given <paramref name="registrationId"/> with the controller.
|
||||
/// </summary>
|
||||
/// <param name="registrationId">The registration <see cref="Guid"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task UnregisterNode(Guid registrationId, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask UnregisterNode(Guid registrationId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Notify the controller that the node with the given <paramref name="registrationId"/> is ready to commit or notify the node of the controller telling it to commit.
|
||||
/// </summary>
|
||||
/// <param name="registrationId">The registration <see cref="Guid"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task<bool> RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask<bool> RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,15 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <param name="fileStreamProvider">The <see cref="ISeekableFileStreamProvider"/> to relay to other nodes.</param>
|
||||
/// <param name="version">The <see cref="Version"/> to update to.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> if the update should proceed, <see langword="false"/> otherwise.</returns>
|
||||
Task<SwarmPrepareResult> PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="true"/> if the update should proceed, <see langword="false"/> otherwise.</returns>
|
||||
ValueTask<SwarmPrepareResult> PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Signal to the swarm that an update is ready to be applied.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="SwarmCommitResult"/>.</returns>
|
||||
Task<SwarmCommitResult> CommitUpdate(CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="SwarmCommitResult"/>.</returns>
|
||||
ValueTask<SwarmCommitResult> CommitUpdate(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="SwarmServerResponse"/>s in the swarm, including the current one.
|
||||
|
||||
@@ -12,14 +12,14 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// Attempt to register with the swarm controller if not one, sets up the database otherwise.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="SwarmRegistrationResult"/>.</returns>
|
||||
Task<SwarmRegistrationResult> Initialize(CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="SwarmRegistrationResult"/>.</returns>
|
||||
ValueTask<SwarmRegistrationResult> Initialize(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Deregister with the swarm controller or put clients into querying state.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task Shutdown(CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask Shutdown(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <summary>
|
||||
/// Attempt to abort an uncommitted update.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
/// <remarks>This method does not accept a <see cref="global::System.Threading.CancellationToken"/> because aborting an update should never be cancelled.</remarks>
|
||||
Task AbortUpdate();
|
||||
ValueTask AbortUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using Microsoft.Extensions.Options;
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
public void Dispose() => serverHealthCheckCancellationTokenSource?.Dispose();
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task AbortUpdate()
|
||||
public async ValueTask AbortUpdate()
|
||||
{
|
||||
if (!SwarmMode)
|
||||
return;
|
||||
@@ -239,7 +240,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SwarmCommitResult> CommitUpdate(CancellationToken cancellationToken)
|
||||
public async ValueTask<SwarmCommitResult> CommitUpdate(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!SwarmMode)
|
||||
return SwarmCommitResult.ContinueUpdateNonCommitted;
|
||||
@@ -311,7 +312,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
// 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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<SwarmPrepareResult> PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken)
|
||||
public ValueTask<SwarmPrepareResult> PrepareUpdate(ISeekableFileStreamProvider fileStreamProvider, Version version, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(fileStreamProvider);
|
||||
|
||||
@@ -371,7 +373,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken)
|
||||
public async ValueTask<bool> PrepareUpdateFromController(SwarmUpdateRequest updateRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(updateRequest);
|
||||
|
||||
@@ -385,7 +387,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SwarmRegistrationResult> Initialize(CancellationToken cancellationToken)
|
||||
public async ValueTask<SwarmRegistrationResult> Initialize(CancellationToken cancellationToken)
|
||||
{
|
||||
if (SwarmMode)
|
||||
logger.LogInformation(
|
||||
@@ -418,11 +420,11 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken)
|
||||
public async ValueTask<bool> RegisterNode(Api.Models.Internal.SwarmServer node, Guid registrationId, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(node);
|
||||
|
||||
@@ -586,7 +589,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken)
|
||||
public async ValueTask<bool> RemoteCommitRecieved(Guid registrationId, CancellationToken cancellationToken)
|
||||
{
|
||||
var localUpdateOperation = updateOperation;
|
||||
if (!swarmController)
|
||||
@@ -635,7 +638,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <summary>
|
||||
/// Sends out remote abort update requests.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
/// <remarks>The aborted <see cref="updateOperation"/> should be cleared out before calling this. This method does not accept a <see cref="CancellationToken"/> because aborting an update should never be cancelled.</remarks>
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
});
|
||||
|
||||
lock (swarmServers)
|
||||
return Task.WhenAll(
|
||||
return ValueTaskExtensions.WhenAll(
|
||||
swarmServers
|
||||
.Where(x => !x.Controller)
|
||||
.Select(SendRemoteAbort));
|
||||
.Select(SendRemoteAbort)
|
||||
.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -753,8 +757,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <param name="initiatorProvider">The <see cref="ISeekableFileStreamProvider"/> containing the update package if this is the initiating server, <see langword="null"/> otherwise.</param>
|
||||
/// <param name="updateRequest">The <see cref="SwarmUpdateRequest"/>. Must always have <see cref="SwarmUpdateRequest.UpdateVersion"/> populated. If <paramref name="initiatorProvider"/> is <see langword="null"/>, it must be fully populated.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="SwarmPrepareResult"/>.</returns>
|
||||
async Task<SwarmPrepareResult> PrepareUpdateImpl(ISeekableFileStreamProvider initiatorProvider, SwarmUpdateRequest updateRequest, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="SwarmPrepareResult"/>.</returns>
|
||||
async ValueTask<SwarmPrepareResult> PrepareUpdateImpl(ISeekableFileStreamProvider initiatorProvider, SwarmUpdateRequest updateRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!SwarmMode)
|
||||
{
|
||||
@@ -916,8 +920,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <param name="updateRequest">The <see cref="SwarmUpdateRequest"/>. Must always have <see cref="SwarmUpdateRequest.UpdateVersion"/> populated. If <paramref name="initiatorProvider"/> is <see langword="null"/>, it must be fully populated.</param>
|
||||
/// <param name="currentUpdateOperation">The current <see cref="SwarmUpdateOperation"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="SwarmPrepareResult"/>.</returns>
|
||||
async Task<SwarmPrepareResult> ControllerDistributedPrepareUpdate(
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="SwarmPrepareResult"/>.</returns>
|
||||
async ValueTask<SwarmPrepareResult> ControllerDistributedPrepareUpdate(
|
||||
ISeekableFileStreamProvider initiatorProvider,
|
||||
SwarmUpdateRequest updateRequest,
|
||||
SwarmUpdateOperation currentUpdateOperation,
|
||||
@@ -1056,8 +1060,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// <param name="initiatorProvider">The <see cref="ISeekableFileStreamProvider"/> containing the server update package.</param>
|
||||
/// <param name="involvedServers">An <see cref="IEnumerable{T}"/> of the involved <see cref="SwarmServerResponse"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in a new <see cref="Dictionary{TKey, TValue}"/> of unique <see cref="FileTicketResponse"/>s keyed by their <see cref="Api.Models.Internal.SwarmServer.Identifier"/>.</returns>
|
||||
async Task<Dictionary<string, FileTicketResponse>> CreateDownloadTickets(
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a new <see cref="Dictionary{TKey, TValue}"/> of unique <see cref="FileTicketResponse"/>s keyed by their <see cref="Api.Models.Internal.SwarmServer.Identifier"/>.</returns>
|
||||
async ValueTask<Dictionary<string, FileTicketResponse>> CreateDownloadTickets(
|
||||
ISeekableFileStreamProvider initiatorProvider,
|
||||
IReadOnlyCollection<SwarmServerResponse> involvedServers,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -1093,8 +1097,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// Ping each node to see that they are still running.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task HealthCheckNodes(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask HealthCheckNodes(CancellationToken cancellationToken)
|
||||
{
|
||||
using var httpClient = httpClientFactory.CreateClient();
|
||||
|
||||
@@ -1102,7 +1106,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
lock (swarmServers)
|
||||
currentSwarmServers = swarmServers.ToList();
|
||||
|
||||
async Task HealthRequestForServer(SwarmServerResponse swarmServer)
|
||||
async ValueTask HealthRequestForServer(SwarmServerResponse swarmServer)
|
||||
{
|
||||
using var request = PrepareSwarmRequest(
|
||||
swarmServer,
|
||||
@@ -1131,7 +1135,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
await ValueTaskExtensions.WhenAll(
|
||||
currentSwarmServers
|
||||
.Where(node => !node.Controller
|
||||
&& registrationIdsAndTimes.TryGetValue(node.Identifier, out var registrationAndTime)
|
||||
@@ -1170,8 +1174,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// Ping the swarm controller to see that it is still running. If need be, reregister.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task HealthCheckController(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask HealthCheckController(CancellationToken cancellationToken)
|
||||
{
|
||||
using var httpClient = httpClientFactory.CreateClient();
|
||||
|
||||
@@ -1227,8 +1231,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// Attempt to register the node with the controller.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="SwarmRegistrationResult"/>.</returns>
|
||||
async Task<SwarmRegistrationResult> RegisterWithController(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="SwarmRegistrationResult"/>.</returns>
|
||||
async ValueTask<SwarmRegistrationResult> RegisterWithController(CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogInformation("Attempting to register with swarm controller at {controllerAddress}...", swarmConfiguration.ControllerAddress);
|
||||
var requestedRegistrationId = Guid.NewGuid();
|
||||
@@ -1289,8 +1293,8 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// Sends the controllers list of nodes to all nodes.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
async Task SendUpdatedServerListToNodes(CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask SendUpdatedServerListToNodes(CancellationToken cancellationToken)
|
||||
{
|
||||
List<SwarmServerResponse> currentSwarmServers;
|
||||
lock (swarmServers)
|
||||
@@ -1308,7 +1312,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
await ValueTaskExtensions.WhenAll(
|
||||
currentSwarmServers
|
||||
.Where(x => !x.Controller)
|
||||
.Select(UpdateRequestForServer));
|
||||
.Select(UpdateRequestForServer)
|
||||
.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -39,8 +39,7 @@ namespace Tgstation.Server.Host.System
|
||||
/// <summary>
|
||||
/// Get the name of the account executing the <see cref="IProcess"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the name of the account executing the <see cref="IProcess"/>.</returns>
|
||||
Task<string> GetExecutingUsername(CancellationToken cancellationToken);
|
||||
/// <returns>The name of the account executing the <see cref="IProcess"/>.</returns>
|
||||
string GetExecutingUsername();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Tgstation.Server.Host.System
|
||||
/// </summary>
|
||||
/// <param name="outputFile">The full path to the output file.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task CreateDump(string outputFile, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CreateDump(string outputFile, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,8 @@ namespace Tgstation.Server.Host.System
|
||||
/// Get the name of the user executing a given <paramref name="process"/>.
|
||||
/// </summary>
|
||||
/// <param name="process">The <see cref="global::System.Diagnostics.Process"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>The name of the user executing <paramref name="process"/>.</returns>
|
||||
Task<string> GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken);
|
||||
string GetExecutingUsername(global::System.Diagnostics.Process process);
|
||||
|
||||
/// <summary>
|
||||
/// Suspend a given <paramref name="process"/>.
|
||||
@@ -34,7 +33,7 @@ namespace Tgstation.Server.Host.System
|
||||
/// <param name="process">The <see cref="Process"/> to dump.</param>
|
||||
/// <param name="outputFile">The full path to the output file.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CreateDump(global::System.Diagnostics.Process process, string outputFile, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +60,11 @@ namespace Tgstation.Server.Host.System
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<string> GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken)
|
||||
public string GetExecutingUsername(global::System.Diagnostics.Process process)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
|
||||
@@ -202,15 +202,15 @@ namespace Tgstation.Server.Host.System
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> 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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task CreateDump(string outputFile, CancellationToken cancellationToken)
|
||||
public ValueTask CreateDump(string outputFile, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(outputFile);
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Tgstation.Server.Host.System
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<string> 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 @@ namespace Tgstation.Server.Host.System
|
||||
?.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";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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
|
||||
{
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace Tgstation.Server.Host.Transfer
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<Tuple<Stream, ErrorMessageResponse>> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken)
|
||||
public async ValueTask<Tuple<Stream, ErrorMessageResponse>> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ticket);
|
||||
|
||||
@@ -217,7 +217,7 @@ namespace Tgstation.Server.Host.Transfer
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ErrorMessageResponse> SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken)
|
||||
public async ValueTask<ErrorMessageResponse> SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ticket);
|
||||
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Tgstation.Server.Host.Transfer
|
||||
/// <param name="ticket">The <see cref="FileTicketResponse"/>.</param>
|
||||
/// <param name="stream">The <see cref="Stream"/> with uploaded data.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns><see langword="null"/> if the upload completed successfully, <see cref="ErrorMessageResponse"/> otherwise.</returns>
|
||||
Task<ErrorMessageResponse> SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="null"/> if the upload completed successfully, <see cref="ErrorMessageResponse"/> otherwise.</returns>
|
||||
ValueTask<ErrorMessageResponse> SetUploadStream(FileTicketResponse ticket, Stream stream, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the the <see cref="Stream"/> for a given <paramref name="ticket"/> associated with a pending download.
|
||||
/// </summary>
|
||||
/// <param name="ticket">The <see cref="FileTicketResponse"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Tuple{T1, T2}"/> containing either a <see cref="Stream"/> containing the data to download or an <see cref="ErrorMessageResponse"/> to return.</returns>
|
||||
Task<Tuple<Stream, ErrorMessageResponse>> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="Tuple{T1, T2}"/> containing either a <see cref="Stream"/> containing the data to download or an <see cref="ErrorMessageResponse"/> to return.</returns>
|
||||
ValueTask<Tuple<Stream, ErrorMessageResponse>> RetrieveDownloadStream(FileTicketResponse ticket, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Tgstation.Server.Host.Utils
|
||||
/// <param name="basePort">The port to check first. Will not allocate a port lower than this.</param>
|
||||
/// <param name="checkOne">If only <paramref name="basePort"/> should be checked and no others.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the first available port on success, <see langword="null"/> on failure.</returns>
|
||||
Task<ushort?> GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the first available port on success, <see langword="null"/> on failure.</returns>
|
||||
ValueTask<ushort?> GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Tgstation.Server.Host.Utils
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ushort?> GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken)
|
||||
public async ValueTask<ushort?> GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("Port allocation >= {basePort} requested...", basePort);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Tgstation.Server.Host.Console.Tests
|
||||
{
|
||||
var mockServer = new Mock<IWatchdog>();
|
||||
var args = Array.Empty<string>();
|
||||
mockServer.Setup(x => x.RunAsync(false, args, It.IsAny<CancellationToken>())).Returns(Task.FromResult(true)).Verifiable();
|
||||
mockServer.Setup(x => x.RunAsync(false, args, It.IsAny<CancellationToken>())).Returns(ValueTask.FromResult(true)).Verifiable();
|
||||
var mockServerFactory = new Mock<IWatchdogFactory>();
|
||||
mockServerFactory.Setup(x => x.CreateWatchdog(It.IsNotNull<ISignalChecker>(), It.IsNotNull<ILoggerFactory>())).Returns(mockServer.Object).Verifiable();
|
||||
Program.WatchdogFactory = mockServerFactory.Object;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Tgstation.Server.Host.Service.Tests
|
||||
var mockWatchdog = new Mock<IWatchdog>();
|
||||
var args = Array.Empty<string>();
|
||||
CancellationToken cancellationToken = default;
|
||||
Task signalCheckerTask = null;
|
||||
ValueTask? signalCheckerTask = null;
|
||||
var childStarted = false;
|
||||
ISignalChecker signalChecker = null;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Service.Tests
|
||||
childStarted = true;
|
||||
return (123, Task.CompletedTask);
|
||||
}, cancellationToken);
|
||||
}).Returns(Task.FromResult(true)).Verifiable();
|
||||
}).Returns(ValueTask.FromResult(true)).Verifiable();
|
||||
var mockWatchdogFactory = new Mock<IWatchdogFactory>();
|
||||
|
||||
mockWatchdogFactory.Setup(x => x.CreateWatchdog(It.IsNotNull<ISignalChecker>(), It.IsNotNull<ILoggerFactory>()))
|
||||
@@ -67,7 +67,7 @@ namespace Tgstation.Server.Host.Service.Tests
|
||||
}
|
||||
|
||||
mockWatchdogFactory.VerifyAll();
|
||||
Assert.IsTrue(signalCheckerTask.IsCompleted);
|
||||
Assert.IsTrue(signalCheckerTask.Value.IsCompleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,28 +88,28 @@ namespace Tgstation.Server.Host.IO.Tests
|
||||
null,
|
||||
tempPath2,
|
||||
throttle,
|
||||
default));
|
||||
default).AsTask());
|
||||
await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => ioManager.CopyDirectory(
|
||||
null,
|
||||
null,
|
||||
tempPath1,
|
||||
null,
|
||||
throttle,
|
||||
default));
|
||||
default).AsTask());
|
||||
await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => ioManager.CopyDirectory(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
throttle,
|
||||
default));
|
||||
default).AsTask());
|
||||
await Assert.ThrowsExceptionAsync<ArgumentOutOfRangeException>(() => ioManager.CopyDirectory(
|
||||
null,
|
||||
null,
|
||||
tempPath1,
|
||||
tempPath2,
|
||||
-1,
|
||||
default));
|
||||
default).AsTask());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -104,10 +104,10 @@ namespace Tgstation.Server.Host.Setup.Tests
|
||||
return $"{paths[0]}/{paths[1]}";
|
||||
}).Verifiable();
|
||||
mockIOManager.Setup(x => x.FileExists(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(true)).Verifiable();
|
||||
mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(Encoding.UTF8.GetBytes("less profane"))).Verifiable();
|
||||
mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(ValueTask.FromResult(Encoding.UTF8.GetBytes("less profane"))).Verifiable();
|
||||
mockIOManager
|
||||
.Setup(x => x.WriteAllBytes(It.IsNotNull<string>(), It.IsNotNull<byte[]>(), It.IsAny<CancellationToken>()))
|
||||
.Returns(Task.CompletedTask)
|
||||
.Returns(ValueTask.CompletedTask)
|
||||
.Verifiable();
|
||||
|
||||
var mockSuccessCommand = new Mock<DbCommand>();
|
||||
@@ -306,7 +306,7 @@ namespace Tgstation.Server.Host.Setup.Tests
|
||||
await RunWizard();
|
||||
|
||||
//second run
|
||||
mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(Encoding.UTF8.GetBytes(String.Empty))).Verifiable();
|
||||
mockIOManager.Setup(x => x.ReadAllBytes(It.IsNotNull<string>(), It.IsAny<CancellationToken>())).Returns(ValueTask.FromResult(Encoding.UTF8.GetBytes(String.Empty))).Verifiable();
|
||||
await RunWizard();
|
||||
|
||||
//third run
|
||||
|
||||
@@ -10,6 +10,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm.Tests
|
||||
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 @@ namespace Tgstation.Server.Host.Swarm.Tests
|
||||
Assert.AreEqual(SwarmRegistrationResult.Success, await controller.TryInit());
|
||||
Assert.AreEqual(SwarmRegistrationResult.Success, await node1.TryInit());
|
||||
|
||||
Task<SwarmPrepareResult> controllerPrepareTask = null, nodePrepareTask;
|
||||
ValueTask<SwarmPrepareResult> controllerPrepareTask = ValueTask.FromResult(SwarmPrepareResult.SuccessProviderNotRequired), nodePrepareTask;
|
||||
if (prepControllerFirst)
|
||||
controllerPrepareTask = controller.Service.PrepareUpdate(updateFileStreamProvider, new Version(4, 3, 2), default);
|
||||
|
||||
@@ -230,7 +231,7 @@ namespace Tgstation.Server.Host.Swarm.Tests
|
||||
|
||||
await Task.Yield();
|
||||
|
||||
await Task.WhenAll(controllerPrepareTask, nodePrepareTask);
|
||||
await ValueTaskExtensions.WhenAll(controllerPrepareTask, nodePrepareTask);
|
||||
|
||||
Task<SwarmCommitResult> nodeCommitTask = null, controllerCommitTask = null;
|
||||
|
||||
@@ -248,13 +249,13 @@ namespace Tgstation.Server.Host.Swarm.Tests
|
||||
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();
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace Tgstation.Server.Host.Swarm.Tests
|
||||
throw new TaskCanceledException();
|
||||
}).Verifiable();
|
||||
|
||||
Task<SwarmRegistrationResult> Invoke() => Service.Initialize(default);
|
||||
Task<SwarmRegistrationResult> Invoke() => Service.Initialize(default).AsTask();
|
||||
|
||||
SwarmRegistrationResult? result;
|
||||
if (cancel)
|
||||
|
||||
@@ -3,7 +3,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Tgstation.Server.Host.IO;
|
||||
|
||||
@@ -26,12 +25,12 @@ namespace Tgstation.Server.Host.System.Tests
|
||||
}
|
||||
|
||||
[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}\"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Tgstation.Server.Api.Models;
|
||||
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 @@ namespace Tgstation.Server.Tests.Live.Instance
|
||||
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<string>(),
|
||||
null,
|
||||
@@ -176,7 +177,7 @@ namespace Tgstation.Server.Tests.Live.Instance
|
||||
|
||||
public Task RunPreWatchdog(CancellationToken cancellationToken) => Task.WhenAll(
|
||||
SequencedApiTests(cancellationToken),
|
||||
SetupDMApiTests(cancellationToken),
|
||||
SetupDMApiTests(cancellationToken).AsTask(),
|
||||
TestPregeneratedFilesExist(cancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Tgstation.Server.Tests.Live.Instance
|
||||
this.accessIdentifier = accessIdentifier;
|
||||
}
|
||||
|
||||
public async Task<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
public async ValueTask<BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user