ValueTask chat Providers

This commit is contained in:
Jordan Dominion
2023-06-19 15:41:22 -04:00
parent 0a68c3adeb
commit a6a01aa155
6 changed files with 87 additions and 83 deletions
@@ -10,6 +10,7 @@ using Newtonsoft.Json;
using Serilog.Context;
using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Host.Components.Chat.Commands;
using Tgstation.Server.Host.Components.Chat.Providers;
using Tgstation.Server.Host.Components.Interop;
@@ -369,7 +370,7 @@ namespace Tgstation.Server.Host.Components.Chat
logger.LogTrace("Sending deployment message for RevisionInformation: {revisionInfoId}", revisionInformation.Id);
var callbacks = new List<Func<string, string, Task>>();
var callbacks = new List<Func<string, string, ValueTask>>();
var task = Task.WhenAll(
wdChannels.Select(
@@ -412,11 +413,12 @@ namespace Tgstation.Server.Host.Components.Chat
async Task CollateTasks(string errorMessage, string dreamMakerOutput)
{
await task;
await Task.WhenAll(
await ValueTaskExtensions.WhenAll(
callbacks.Select(
x => x(
errorMessage,
dreamMakerOutput)));
dreamMakerOutput)),
callbacks.Count);
}
return (errorMessage, dreamMakerOutput) => AddMessageTask(CollateTasks(errorMessage, dreamMakerOutput));
@@ -928,7 +930,9 @@ namespace Tgstation.Server.Host.Components.Chat
lock (providers)
foreach (var providerKvp in providers)
if (!messageTasks.ContainsKey(providerKvp.Value))
messageTasks.Add(providerKvp.Value, providerKvp.Value.NextMessage(cancellationToken));
messageTasks.Add(
providerKvp.Value,
providerKvp.Value.NextMessage(cancellationToken).AsTask());
if (messageTasks.Count == 0)
{
@@ -999,30 +1003,32 @@ namespace Tgstation.Server.Host.Components.Chat
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task SendMessage(IEnumerable<ulong> channelIds, Message replyTo, MessageContent message, CancellationToken cancellationToken)
{
channelIds = channelIds.ToList();
var channelIdsList = channelIds.ToList();
logger.LogTrace(
"Chat send \"{message}\"{embed} to channels: [{channelIdsCommaSeperated}]",
message.Text,
message.Embed != null ? " (with embed)" : String.Empty,
String.Join(", ", channelIds));
String.Join(", ", channelIdsList));
if (!channelIds.Any())
if (!channelIdsList.Any())
return Task.CompletedTask;
return Task.WhenAll(
channelIds.Select(x =>
return ValueTaskExtensions.WhenAll(
channelIdsList.Select(x =>
{
ChannelMapping channelMapping;
lock (mappedChannels)
if (!mappedChannels.TryGetValue(x, out channelMapping))
return Task.CompletedTask;
return ValueTask.CompletedTask;
IProvider provider;
lock (providers)
if (!providers.TryGetValue(channelMapping.ProviderId, out provider))
return Task.CompletedTask;
return ValueTask.CompletedTask;
return provider.SendMessage(replyTo, message, channelMapping.ProviderChannelId, cancellationToken);
}));
}),
channelIdsList.Count)
.AsTask();
}
/// <summary>
@@ -25,6 +25,7 @@ using Remora.Rest.Results;
using Remora.Results;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Jobs;
@@ -285,7 +286,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public override async Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken)
public override async ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(message);
@@ -376,7 +377,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public override async Task<Func<string, string, Task>> SendUpdateMessage(
public override async ValueTask<Func<string, string, ValueTask>> SendUpdateMessage(
Models.RevisionInformation revisionInformation,
Version byondVersion,
DateTimeOffset? estimatedCompletionTime,
@@ -628,7 +629,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
protected override async Task Connect(CancellationToken cancellationToken)
protected override async ValueTask Connect(CancellationToken cancellationToken)
{
try
{
@@ -688,7 +689,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
protected override async Task DisconnectImpl(CancellationToken cancellationToken)
protected override async ValueTask DisconnectImpl(CancellationToken cancellationToken)
{
Task<Result> localGatewayTask;
CancellationTokenSource localGatewayCts;
@@ -713,14 +714,14 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
protected override async Task<Dictionary<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(IEnumerable<Models.ChatChannel> channels, CancellationToken cancellationToken)
protected override async ValueTask<Dictionary<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(IEnumerable<Models.ChatChannel> channels, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(channels);
var remapRequired = false;
var guildsClient = serviceProvider.GetRequiredService<IDiscordRestGuildAPI>();
async Task<Tuple<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> GetModelChannelFromDBChannel(Models.ChatChannel channelFromDB)
async ValueTask<Tuple<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> GetModelChannelFromDBChannel(Models.ChatChannel channelFromDB)
{
if (!channelFromDB.DiscordChannelId.HasValue)
throw new InvalidOperationException("ChatChannel missing DiscordChannelId!");
@@ -785,10 +786,13 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
var tasks = channels
.Where(x => x.DiscordChannelId != 0)
.Select(GetModelChannelFromDBChannel)
.ToList();
.Select(GetModelChannelFromDBChannel);
await Task.WhenAll(tasks);
var channelTuples = await ValueTaskExtensions.WhenAll(tasks.ToList());
var enumerator = channelTuples
.Where(x => x != null)
.ToList();
var channelIdZeroModel = channels.FirstOrDefault(x => x.DiscordChannelId == 0);
if (channelIdZeroModel != null)
@@ -798,7 +802,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
var unmappedTextChannels = allAccessibleChannels
.Where(x => !tasks.Any(task => task.Result != null && new Snowflake(task.Result.Item1.DiscordChannelId.Value) == x.ID));
async Task<Tuple<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> CreateMappingsForUnmappedChannels()
async ValueTask<Tuple<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> CreateMappingsForUnmappedChannels()
{
var unmappedTasks =
unmappedTextChannels.Select(
@@ -835,15 +839,10 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
var task = CreateMappingsForUnmappedChannels();
await task;
tasks.Add(task);
var tuple = await task;
enumerator.Add(tuple);
}
var enumerator = tasks
.Select(x => x.Result)
.Where(x => x != null)
.ToList();
lock (mappedChannels)
{
mappedChannels.Clear();
@@ -864,7 +863,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in an <see cref="IEnumerable{T}"/> of accessible and compatible <see cref="IChannel"/>s.</returns>
async Task<IEnumerable<IChannel>> GetAllAccessibleTextChannels(CancellationToken cancellationToken)
async ValueTask<IEnumerable<IChannel>> GetAllAccessibleTextChannels(CancellationToken cancellationToken)
{
var usersClient = serviceProvider.GetRequiredService<IDiscordRestUserAPI>();
var currentGuildsResponse = await usersClient.GetCurrentUserGuildsAsync(ct: cancellationToken);
@@ -878,7 +877,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
var guildsClient = serviceProvider.GetRequiredService<IDiscordRestGuildAPI>();
async Task<IEnumerable<IChannel>> GetGuildChannels(IPartialGuild guild)
async ValueTask<IEnumerable<IChannel>> GetGuildChannels(IPartialGuild guild)
{
var channelsTask = guildsClient.GetGuildChannelsAsync(guild.ID.Value, cancellationToken);
var threads = await guildsClient.ListActiveGuildThreadsAsync(guild.ID.Value, cancellationToken);
@@ -907,13 +906,12 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
var guildsChannelsTasks = currentGuildsResponse.Entity
.Select(GetGuildChannels)
.ToList();
.Select(GetGuildChannels);
await Task.WhenAll(guildsChannelsTasks);
var guildsChannels = await ValueTaskExtensions.WhenAll(guildsChannelsTasks, currentGuildsResponse.Entity.Count);
var allAccessibleChannels = guildsChannelsTasks
.SelectMany(task => task.Result)
var allAccessibleChannels = guildsChannels
.SelectMany(channels => channels)
.Where(guildChannel => SupportedGuildChannelTypes.Contains(guildChannel.Type));
return allAccessibleChannels;
@@ -39,27 +39,27 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
void InitialMappingComplete();
/// <summary>
/// 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.
/// 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.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <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)"/>. Do not <see cref="IDisposable.Dispose"/> the <see cref="IProvider"/> on continuations run from the returned <see cref="Task"/>.</remarks>
Task<Message> NextMessage(CancellationToken cancellationToken);
/// <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>
/// <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);
/// <summary>
/// Gracefully disconnects the provider. Permanently stops the reconnection timer.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task Disconnect(CancellationToken cancellationToken);
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
ValueTask Disconnect(CancellationToken cancellationToken);
/// <summary>
/// Get the <see cref="ChannelRepresentation"/>s for given <paramref name="channels"/>.
/// </summary>
/// <param name="channels">The <see cref="Api.Models.ChatChannel"/>s to map.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="Dictionary{TKey, TValue}"/> of the <see cref="ChatChannel"/>'s <see cref="ChannelRepresentation"/>s representing <paramref name="channels"/>.</returns>
Task<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannels(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken);
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="Dictionary{TKey, TValue}"/> of the <see cref="ChatChannel"/>'s <see cref="ChannelRepresentation"/>s representing <paramref name="channels"/>.</returns>
ValueTask<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannels(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken);
/// <summary>
/// Send a message to the <see cref="IProvider"/>.
@@ -68,8 +68,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// <param name="message">The <see cref="MessageContent"/>.</param>
/// <param name="channelId">The <see cref="ChannelRepresentation.RealId"/> to send to.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken);
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken);
/// <summary>
/// Set the interval at which the provider starts jobs to try to reconnect.
@@ -90,8 +90,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// <param name="channelId">The <see cref="ChannelRepresentation.RealId"/> to send to.</param>
/// <param name="localCommitPushed"><see langword="true"/> if the local deployment commit was pushed to the remote repository.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="Func{T1, T2, TResult}"/> to call to update the message at the deployment's conclusion. Parameters: Error message if any, DreamMaker output if any.</returns>
Task<Func<string, string, Task>> SendUpdateMessage(
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="Func{T1, T2, TResult}"/> to call to update the message at the deployment's conclusion. Parameters: Error message if any, DreamMaker output if any.</returns>
ValueTask<Func<string, string, ValueTask>> SendUpdateMessage(
RevisionInformation revisionInformation,
Version byondVersion,
DateTimeOffset? estimatedCompletionTime,
@@ -88,7 +88,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
ulong channelIdCounter;
/// <summary>
/// The <see cref="Task"/> used for <see cref="IrcConnection.Listen(bool)"/>.
/// The <see cref="ValueTask"/> used for <see cref="IrcConnection.Listen(bool)"/>.
/// </summary>
Task listenTask;
@@ -164,11 +164,11 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public override Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken)
public override async ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(message);
return Task.Factory.StartNew(
await Task.Factory.StartNew(
() =>
{
// IRC doesn't allow newlines
@@ -218,7 +218,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public override async Task<Func<string, string, Task>> SendUpdateMessage(
public override async ValueTask<Func<string, string, ValueTask>> SendUpdateMessage(
Models.RevisionInformation revisionInformation,
Version byondVersion,
DateTimeOffset? estimatedCompletionTime,
@@ -292,10 +292,10 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
protected override Task<Dictionary<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(
protected override async ValueTask<Dictionary<Models.ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(
IEnumerable<Models.ChatChannel> channels,
CancellationToken cancellationToken)
=> Task.Factory.StartNew(
=> await Task.Factory.StartNew(
() =>
{
if (channels.Any(x => x.IrcChannel == null))
@@ -366,7 +366,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
TaskScheduler.Current);
/// <inheritdoc />
protected override async Task Connect(CancellationToken cancellationToken)
protected override async ValueTask Connect(CancellationToken cancellationToken)
{
disconnecting = false;
cancellationToken.ThrowIfCancellationRequested();
@@ -455,7 +455,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
protected override async Task DisconnectImpl(CancellationToken cancellationToken)
protected override async ValueTask DisconnectImpl(CancellationToken cancellationToken)
{
try
{
@@ -85,7 +85,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
ChatBot = chatBot ?? throw new ArgumentNullException(nameof(chatBot));
messageQueue = new Queue<Message>();
nextMessage = new TaskCompletionSource();
nextMessage = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
initialConnectionTcs = new TaskCompletionSource();
reconnectTaskLock = new object();
@@ -113,7 +113,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public async Task Disconnect(CancellationToken cancellationToken)
public async ValueTask Disconnect(CancellationToken cancellationToken)
{
await StopReconnectionTimer();
@@ -129,7 +129,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
public void InitialMappingComplete() => initialConnectionTcs.TrySetResult();
/// <inheritdoc />
public async Task<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannels(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken)
public async ValueTask<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannels(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(channels);
@@ -145,7 +145,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public async Task<Message> NextMessage(CancellationToken cancellationToken)
public async ValueTask<Message> NextMessage(CancellationToken cancellationToken)
{
while (true)
{
@@ -172,17 +172,17 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
{
stopOldTimerTask = StopReconnectionTimer();
reconnectCts = new CancellationTokenSource();
reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token);
reconnectTask = ReconnectionLoop(reconnectInterval, connectNow, reconnectCts.Token).AsTask();
}
return stopOldTimerTask;
}
/// <inheritdoc />
public abstract Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken);
public abstract ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken);
/// <inheritdoc />
public abstract Task<Func<string, string, Task>> SendUpdateMessage(
public abstract ValueTask<Func<string, string, ValueTask>> SendUpdateMessage(
RevisionInformation revisionInformation,
Version byondVersion,
DateTimeOffset? estimatedCompletionTime,
@@ -196,23 +196,23 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// Attempt to connect the <see cref="Provider"/>.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
protected abstract Task Connect(CancellationToken cancellationToken);
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
protected abstract ValueTask Connect(CancellationToken cancellationToken);
/// <summary>
/// Gracefully disconnects the provider.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
protected abstract Task DisconnectImpl(CancellationToken cancellationToken);
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
protected abstract ValueTask DisconnectImpl(CancellationToken cancellationToken);
/// <summary>
/// Implementation of <see cref="MapChannels(IEnumerable{ChatChannel}, CancellationToken)"/>.
/// </summary>
/// <param name="channels">The <see cref="ChatChannel"/>s to map.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="Dictionary{TKey, TValue}"/> of the <see cref="ChatChannel"/>'s <see cref="ChannelRepresentation"/>s representing <paramref name="channels"/>.</returns>
protected abstract Task<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="Dictionary{TKey, TValue}"/> of the <see cref="ChatChannel"/>'s <see cref="ChannelRepresentation"/>s representing <paramref name="channels"/>.</returns>
protected abstract ValueTask<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(
IEnumerable<ChatChannel> channels,
CancellationToken cancellationToken);
@@ -245,7 +245,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
reconnectCts.Cancel();
reconnectCts.Dispose();
reconnectCts = null;
Task reconnectTask = this.reconnectTask;
var reconnectTask = this.reconnectTask;
this.reconnectTask = null;
return reconnectTask;
}
@@ -261,8 +261,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="Task"/> representing the running operation.</returns>
async Task ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken)
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
async ValueTask ReconnectionLoop(uint reconnectInterval, bool connectNow, CancellationToken cancellationToken)
{
do
{
@@ -84,7 +84,7 @@ namespace Tgstation.Server.Tests.Live
await base.DisposeAsync();
}
public override Task SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken)
public override ValueTask SendMessage(Message replyTo, MessageContent message, ulong channelId, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(message);
@@ -96,10 +96,10 @@ namespace Tgstation.Server.Tests.Live
if (random.Next(0, 100) > 70)
throw new Exception("Random SendMessage failure!"); */
return Task.CompletedTask;
return ValueTask.CompletedTask;
}
public override Task<Func<string, string, Task>> SendUpdateMessage(RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, string gitHubOwner, string gitHubRepo, ulong channelId, bool localCommitPushed, CancellationToken cancellationToken)
public override ValueTask<Func<string, string, ValueTask>> SendUpdateMessage(RevisionInformation revisionInformation, Version byondVersion, DateTimeOffset? estimatedCompletionTime, string gitHubOwner, string gitHubRepo, ulong channelId, bool localCommitPushed, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(revisionInformation);
ArgumentNullException.ThrowIfNull(byondVersion);
@@ -114,7 +114,7 @@ namespace Tgstation.Server.Tests.Live
if (random.Next(0, 100) > 70)
throw new Exception("Random SendUpdateMessage failure!"); */
return Task.FromResult<Func<string, string, Task>>((_, _) =>
return ValueTask.FromResult<Func<string, string, ValueTask>>((_, _) =>
{
cancellationToken.ThrowIfCancellationRequested();
@@ -122,11 +122,11 @@ namespace Tgstation.Server.Tests.Live
if (random.Next(0, 100) > 70)
throw new Exception("Random SendUpdateMessage failure!"); */
return Task.CompletedTask;
return ValueTask.CompletedTask;
});
}
protected override Task Connect(CancellationToken cancellationToken)
protected override ValueTask Connect(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -136,20 +136,20 @@ namespace Tgstation.Server.Tests.Live
connected = true;
connectedOnce = true;
return Task.CompletedTask;
return ValueTask.CompletedTask;
}
protected override Task DisconnectImpl(CancellationToken cancellationToken)
protected override ValueTask DisconnectImpl(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
connected = false;
if (random.Next(0, 100) > 70)
throw new Exception("Random disconnection failure!");
return Task.CompletedTask;
return ValueTask.CompletedTask;
}
protected override Task<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken)
protected override ValueTask<Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>> MapChannelsImpl(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken)
{
channels = channels.ToList();
@@ -159,7 +159,7 @@ namespace Tgstation.Server.Tests.Live
if (random.Next(0, 100) > 70)
throw new Exception("Random MapChannelsImpl failure!"); */
return Task.FromResult(
return ValueTask.FromResult(
new Dictionary<ChatChannel, IEnumerable<ChannelRepresentation>>(
channels.Select(
channel => new KeyValuePair<ChatChannel, IEnumerable<ChannelRepresentation>>(