Replace a bunch of Task.Delays with IAsyncDelayer

This commit is contained in:
Dominion
2023-05-23 01:27:10 -04:00
parent 70c635ff8c
commit f289c82983
9 changed files with 77 additions and 28 deletions
@@ -27,6 +27,7 @@ using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.Components.Chat.Providers
{
@@ -179,15 +180,17 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// Initializes a new instance of the <see cref="DiscordProvider"/> class.
/// </summary>
/// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="Provider"/>.</param>
/// <param name="assemblyInformationProvider">The value of <see cref="assemblyInformationProvider"/>.</param>
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="Provider"/>.</param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="Provider"/>.</param>
/// <param name="assemblyInformationProvider">The value of <see cref="assemblyInformationProvider"/>.</param>
/// <param name="chatBot">The <see cref="ChatBot"/> for the <see cref="Provider"/>.</param>
public DiscordProvider(
IJobManager jobManager,
IAssemblyInformationProvider assemblyInformationProvider,
IAsyncDelayer asyncDelayer,
ILogger<DiscordProvider> logger,
IAssemblyInformationProvider assemblyInformationProvider,
ChatBot chatBot)
: base(jobManager, logger, chatBot)
: base(jobManager, asyncDelayer, logger, chatBot)
{
this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
@@ -42,11 +42,6 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// <inheritdoc />
public override string BotMention => client.Nickname;
/// <summary>
/// The <see cref="IAsyncDelayer"/> for the <see cref="IrcProvider"/>.
/// </summary>
readonly IAsyncDelayer asyncDelayer;
/// <summary>
/// The <see cref="IrcFeatures"/> client.
/// </summary>
@@ -105,24 +100,22 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// <summary>
/// Initializes a new instance of the <see cref="IrcProvider"/> class.
/// </summary>
/// <param name="jobManager">The <see cref="IJobManager"/> for the provider.</param>
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/> to get the <see cref="IAssemblyInformationProvider.VersionString"/> from.</param>
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
/// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="Provider"/>.</param>
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="Provider"/>.</param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="Provider"/>.</param>
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/> to get the <see cref="IAssemblyInformationProvider.VersionString"/> from.</param>
/// <param name="chatBot">The <see cref="Models.ChatBot"/> for the <see cref="Provider"/>.</param>
public IrcProvider(
IJobManager jobManager,
IAssemblyInformationProvider assemblyInformationProvider,
IAsyncDelayer asyncDelayer,
ILogger<IrcProvider> logger,
IAssemblyInformationProvider assemblyInformationProvider,
Models.ChatBot chatBot)
: base(jobManager, logger, chatBot)
: base(jobManager, asyncDelayer, logger, chatBot)
{
if (assemblyInformationProvider == null)
throw new ArgumentNullException(nameof(assemblyInformationProvider));
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
var builder = chatBot.CreateConnectionStringBuilder();
if (builder == null || !builder.Valid || builder is not IrcConnectionStringBuilder ircBuilder)
throw new InvalidOperationException("Invalid ChatConnectionStringBuilder!");
@@ -641,14 +634,14 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
var listenTimeSpan = TimeSpan.FromMilliseconds(10);
for (; !recievedAck;
await asyncDelayer.Delay(listenTimeSpan, timeoutToken))
await AsyncDelayer.Delay(listenTimeSpan, timeoutToken))
await NonBlockingListen(cancellationToken);
client.WriteLine("AUTHENTICATE PLAIN", Priority.Critical);
timeoutToken.ThrowIfCancellationRequested();
for (; !recievedPlus;
await asyncDelayer.Delay(listenTimeSpan, timeoutToken))
await AsyncDelayer.Delay(listenTimeSpan, timeoutToken))
await NonBlockingListen(cancellationToken);
}
finally
@@ -714,8 +707,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
Task.WhenAll(
disconnectTask,
listenTask ?? Task.CompletedTask),
asyncDelayer.Delay(TimeSpan.FromSeconds(5), cancellationToken))
;
AsyncDelayer.Delay(TimeSpan.FromSeconds(5), cancellationToken));
}
}
}
@@ -10,6 +10,7 @@ using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.Components.Chat.Providers
{
@@ -24,6 +25,11 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// </summary>
protected ChatBot ChatBot { get; }
/// <summary>
/// The <see cref="IAsyncDelayer"/> for the <see cref="Provider"/>.
/// </summary>
protected IAsyncDelayer AsyncDelayer { get; }
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="Provider"/>.
/// </summary>
@@ -68,11 +74,13 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// Initializes a new instance of the <see cref="Provider"/> class.
/// </summary>
/// <param name="jobManager">The value of <see cref="jobManager"/>.</param>
/// <param name="asyncDelayer">The value of <see cref="AsyncDelayer"/>.</param>
/// <param name="logger">The value of <see cref="Logger"/>.</param>
/// <param name="chatBot">The value of <paramref name="chatBot"/>.</param>
protected Provider(IJobManager jobManager, ILogger<Provider> logger, ChatBot chatBot)
protected Provider(IJobManager jobManager, IAsyncDelayer asyncDelayer, ILogger<Provider> logger, ChatBot chatBot)
{
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
AsyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
ChatBot = chatBot ?? throw new ArgumentNullException(nameof(chatBot));
@@ -259,7 +267,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
try
{
if (!connectNow)
await Task.Delay(TimeSpan.FromMinutes(reconnectInterval), cancellationToken);
await AsyncDelayer.Delay(TimeSpan.FromMinutes(reconnectInterval), cancellationToken);
else
connectNow = false;
if (!Connected)
@@ -61,14 +61,15 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
{
ChatProvider.Irc => new IrcProvider(
jobManager,
assemblyInformationProvider,
asyncDelayer,
loggerFactory.CreateLogger<IrcProvider>(),
assemblyInformationProvider,
settings),
ChatProvider.Discord => new DiscordProvider(
jobManager,
assemblyInformationProvider,
asyncDelayer,
loggerFactory.CreateLogger<DiscordProvider>(),
assemblyInformationProvider,
settings),
_ => throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid ChatProvider: {0}", settings.Provider)),
};
@@ -23,6 +23,7 @@ using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.Components.Deployment
{
@@ -89,6 +90,11 @@ namespace Tgstation.Server.Host.Components.Deployment
/// </summary>
readonly IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory;
/// <summary>
/// The <see cref="IAsyncDelayer"/> for <see cref="DreamMaker"/>.
/// </summary>
readonly IAsyncDelayer asyncDelayer;
/// <summary>
/// The <see cref="ILogger"/> for <see cref="DreamMaker"/>.
/// </summary>
@@ -147,6 +153,7 @@ namespace Tgstation.Server.Host.Components.Deployment
/// <param name="compileJobConsumer">The value of <see cref="compileJobConsumer"/>.</param>
/// <param name="repositoryManager">The value of <see cref="repositoryManager"/>.</param>
/// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
/// <param name="sessionConfiguration">The value of <see cref="sessionConfiguration"/>.</param>
/// <param name="metadata">The value of <see cref="metadata"/>.</param>
@@ -161,6 +168,7 @@ namespace Tgstation.Server.Host.Components.Deployment
ICompileJobSink compileJobConsumer,
IRepositoryManager repositoryManager,
IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
IAsyncDelayer asyncDelayer,
ILogger<DreamMaker> logger,
SessionConfiguration sessionConfiguration,
Api.Models.Instance metadata)
@@ -174,6 +182,7 @@ namespace Tgstation.Server.Host.Components.Deployment
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
this.compileJobConsumer = compileJobConsumer ?? throw new ArgumentNullException(nameof(compileJobConsumer));
this.repositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
@@ -741,13 +750,13 @@ namespace Tgstation.Server.Host.Components.Deployment
var remainingSleepThisInterval = nextInterval - DateTimeOffset.UtcNow;
var nextSleepSpan = remainingSleepThisInterval < minimumSleepInterval ? minimumSleepInterval : remainingSleepThisInterval;
await Task.Delay(nextSleepSpan, cancellationToken);
await asyncDelayer.Delay(nextSleepSpan, cancellationToken);
progressReporter.ReportProgress(lastReport);
}
while (DateTimeOffset.UtcNow < nextInterval);
}
else
await Task.Delay(minimumSleepInterval, cancellationToken);
await asyncDelayer.Delay(minimumSleepInterval, cancellationToken);
lastReport = estimatedDuration.HasValue ? sleepInterval * (iteration + 1) / estimatedDuration.Value : null;
progressReporter.ReportProgress(lastReport);
@@ -70,6 +70,11 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory;
/// <summary>
/// The <see cref="IAsyncDelayer"/> for the <see cref="Instance"/>.
/// </summary>
readonly IAsyncDelayer asyncDelayer;
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="Instance"/>.
/// </summary>
@@ -109,6 +114,7 @@ namespace Tgstation.Server.Host.Components
/// <param name="jobManager">The value of <see cref="jobManager"/>.</param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/>.</param>
/// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
public Instance(
Api.Models.Instance metadata,
@@ -123,6 +129,7 @@ namespace Tgstation.Server.Host.Components
IJobManager jobManager,
IEventConsumer eventConsumer,
IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
IAsyncDelayer asyncDelayer,
ILogger<Instance> logger)
{
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
@@ -136,6 +143,7 @@ namespace Tgstation.Server.Host.Components
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
timerLock = new object();
@@ -488,7 +496,7 @@ namespace Tgstation.Server.Host.Components
while (true)
try
{
await Task.Delay(TimeSpan.FromMinutes(minutes > Int32.MaxValue ? Int32.MaxValue : minutes), cancellationToken);
await asyncDelayer.Delay(TimeSpan.FromMinutes(minutes > Int32.MaxValue ? Int32.MaxValue : minutes), cancellationToken);
logger.LogInformation("Beginning auto update...");
await eventConsumer.HandleEvent(EventType.InstanceAutoUpdateStart, Enumerable.Empty<string>(), cancellationToken);
try
@@ -23,6 +23,7 @@ using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Security;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Transfer;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.Components
{
@@ -139,6 +140,11 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory;
/// <summary>
/// The <see cref="IAsyncDelayer"/> for the <see cref="InstanceFactory"/>.
/// </summary>
readonly IAsyncDelayer asyncDelayer;
/// <summary>
/// The <see cref="GeneralConfiguration"/> for the <see cref="InstanceFactory"/>.
/// </summary>
@@ -182,6 +188,7 @@ namespace Tgstation.Server.Host.Components
/// <param name="fileTransferService">The value of <see cref="fileTransferService"/>.</param>
/// <param name="gitRemoteFeaturesFactory">The value of <see cref="gitRemoteFeaturesFactory"/>.</param>
/// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="generalConfiguration"/>.</param>
/// <param name="sessionConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="sessionConfiguration"/>.</param>
public InstanceFactory(
@@ -207,6 +214,7 @@ namespace Tgstation.Server.Host.Components
IFileTransferTicketProvider fileTransferService,
IGitRemoteFeaturesFactory gitRemoteFeaturesFactory,
IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
IAsyncDelayer asyncDelayer,
IOptions<GeneralConfiguration> generalConfigurationOptions,
IOptions<SessionConfiguration> sessionConfigurationOptions)
{
@@ -232,6 +240,7 @@ namespace Tgstation.Server.Host.Components
this.fileTransferService = fileTransferService ?? throw new ArgumentNullException(nameof(fileTransferService));
this.gitRemoteFeaturesFactory = gitRemoteFeaturesFactory ?? throw new ArgumentNullException(nameof(gitRemoteFeaturesFactory));
this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
sessionConfiguration = sessionConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions));
}
@@ -310,6 +319,7 @@ namespace Tgstation.Server.Host.Components
bridgeRegistrar,
serverPortProvider,
eventConsumer,
asyncDelayer,
loggerFactory,
loggerFactory.CreateLogger<SessionControllerFactory>(),
sessionConfiguration,
@@ -358,6 +368,7 @@ namespace Tgstation.Server.Host.Components
dmbFactory,
repoManager,
remoteDeploymentManagerFactory,
asyncDelayer,
loggerFactory.CreateLogger<DreamMaker>(),
sessionConfiguration,
metadata);
@@ -374,6 +385,7 @@ namespace Tgstation.Server.Host.Components
jobManager,
eventConsumer,
remoteDeploymentManagerFactory,
asyncDelayer,
loggerFactory.CreateLogger<Instance>());
return instance;
@@ -180,6 +180,7 @@ namespace Tgstation.Server.Host.Components.Session
/// <param name="chat">The value of <see cref="chat"/>.</param>
/// <param name="chatTrackingContext">The value of <see cref="chatTrackingContext"/>.</param>
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/> for the <see cref="SessionController"/>.</param>
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="SessionController"/>.</param>
/// <param name="logger">The value of <see cref="Chunker.Logger"/>.</param>
/// <param name="postLifetimeCallback">The <see cref="Func{TResult}"/> returning a <see cref="Task"/> to be run after the <paramref name="process"/> ends.</param>
/// <param name="startupTimeout">The optional time to wait before failing the <see cref="LaunchResult"/>.</param>
@@ -195,6 +196,7 @@ namespace Tgstation.Server.Host.Components.Session
IBridgeRegistrar bridgeRegistrar,
IChatManager chat,
IAssemblyInformationProvider assemblyInformationProvider,
IAsyncDelayer asyncDelayer,
ILogger<SessionController> logger,
Func<Task> postLifetimeCallback,
uint? startupTimeout,
@@ -250,6 +252,7 @@ namespace Tgstation.Server.Host.Components.Session
LaunchResult = GetLaunchResult(
assemblyInformationProvider,
asyncDelayer,
startupTimeout,
reattached,
apiValidate);
@@ -512,12 +515,14 @@ namespace Tgstation.Server.Host.Components.Session
/// The <see cref="Task{TResult}"/> for <see cref="LaunchResult"/>.
/// </summary>
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/>.</param>
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/>.</param>
/// <param name="startupTimeout">The, optional, startup timeout in seconds.</param>
/// <param name="reattached">If DreamDaemon was reattached.</param>
/// <param name="apiValidate">If this is a DMAPI validation session.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="Session.LaunchResult"/> for the operation.</returns>
async Task<LaunchResult> GetLaunchResult(
IAssemblyInformationProvider assemblyInformationProvider,
IAsyncDelayer asyncDelayer,
uint? startupTimeout,
bool reattached,
bool apiValidate)
@@ -530,7 +535,7 @@ namespace Tgstation.Server.Host.Components.Session
var toAwait = Task.WhenAny(startupTask, process.Lifetime);
if (startupTimeout.HasValue)
toAwait = Task.WhenAny(toAwait, Task.Delay(TimeSpan.FromSeconds(startupTimeout.Value)));
toAwait = Task.WhenAny(toAwait, asyncDelayer.Delay(TimeSpan.FromSeconds(startupTimeout.Value), default)); // DCT: None available, task will clean up after delay
Logger.LogTrace(
"Waiting for LaunchResult based on {launchResultCompletionCause}{possibleTimeout}...",
@@ -26,6 +26,7 @@ using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Security;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Utils;
namespace Tgstation.Server.Host.Components.Session
{
@@ -102,6 +103,11 @@ namespace Tgstation.Server.Host.Components.Session
/// </summary>
readonly IEventConsumer eventConsumer;
/// <summary>
/// The <see cref="IAsyncDelayer"/> for the <see cref="SessionControllerFactory"/>.
/// </summary>
readonly IAsyncDelayer asyncDelayer;
/// <summary>
/// The <see cref="ILoggerFactory"/> for the <see cref="SessionControllerFactory"/>.
/// </summary>
@@ -187,10 +193,11 @@ namespace Tgstation.Server.Host.Components.Session
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/>.</param>
/// <param name="bridgeRegistrar">The value of <see cref="bridgeRegistrar"/>.</param>
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/>.</param>
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
/// <param name="loggerFactory">The value of <see cref="loggerFactory"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
/// <param name="sessionConfiguration">The value of <see cref="sessionConfiguration"/>.</param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/>.</param>
public SessionControllerFactory(
IProcessExecutor processExecutor,
IByondManager byond,
@@ -205,6 +212,7 @@ namespace Tgstation.Server.Host.Components.Session
IBridgeRegistrar bridgeRegistrar,
IServerPortProvider serverPortProvider,
IEventConsumer eventConsumer,
IAsyncDelayer asyncDelayer,
ILoggerFactory loggerFactory,
ILogger<SessionControllerFactory> logger,
SessionConfiguration sessionConfiguration,
@@ -223,6 +231,7 @@ namespace Tgstation.Server.Host.Components.Session
this.bridgeRegistrar = bridgeRegistrar ?? throw new ArgumentNullException(nameof(bridgeRegistrar));
this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider));
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
@@ -341,6 +350,7 @@ namespace Tgstation.Server.Host.Components.Session
bridgeRegistrar,
chat,
assemblyInformationProvider,
asyncDelayer,
loggerFactory.CreateLogger<SessionController>(),
() => !launchParameters.LogOutput.Value
? LogDDOutput(process, outputFilePath, byondLock.SupportsCli, default) // DCT: None available
@@ -425,6 +435,7 @@ namespace Tgstation.Server.Host.Components.Session
bridgeRegistrar,
chat,
assemblyInformationProvider,
asyncDelayer,
loggerFactory.CreateLogger<SessionController>(),
() => Task.CompletedTask,
null,