mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-27 15:07:03 +01:00
Remove Executor and Session
This commit is contained in:
@@ -52,11 +52,6 @@ namespace Tgstation.Server.Host.Components
|
||||
/// </summary>
|
||||
readonly ICryptographySuite cryptographySuite;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IExecutor"/> for the <see cref="InstanceFactory"/>
|
||||
/// </summary>
|
||||
readonly IExecutor executor;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ISynchronousIOManager"/> for the <see cref="InstanceFactory"/>
|
||||
/// </summary>
|
||||
@@ -92,13 +87,12 @@ namespace Tgstation.Server.Host.Components
|
||||
/// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
|
||||
/// <param name="serverUpdater">The value of <see cref="serverUpdater"/></param>
|
||||
/// <param name="cryptographySuite">The value of <see cref="cryptographySuite"/></param>
|
||||
/// <param name="executor">The value of <see cref="executor"/></param>
|
||||
/// <param name="synchronousIOManager">The value of <see cref="synchronousIOManager"/></param>
|
||||
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/></param>
|
||||
/// <param name="byondInstaller">The value of <see cref="byondInstaller"/></param>
|
||||
/// <param name="providerFactory">The value of <see cref="providerFactory"/></param>
|
||||
/// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
|
||||
public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, IServerControl serverUpdater, ICryptographySuite cryptographySuite, IExecutor executor, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IProviderFactory providerFactory, IProcessExecutor processExecutor)
|
||||
public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, IServerControl serverUpdater, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IProviderFactory providerFactory, IProcessExecutor processExecutor)
|
||||
{
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
|
||||
@@ -106,8 +100,7 @@ namespace Tgstation.Server.Host.Components
|
||||
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
|
||||
this.byondTopicSender = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
|
||||
this.serverUpdater = serverUpdater ?? throw new ArgumentNullException(nameof(serverUpdater));
|
||||
this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite ));
|
||||
this.executor = executor ?? throw new ArgumentNullException(nameof(executor));
|
||||
this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
|
||||
this.synchronousIOManager = synchronousIOManager ?? throw new ArgumentNullException(nameof(synchronousIOManager));
|
||||
this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
|
||||
this.byondInstaller = byondInstaller ?? throw new ArgumentNullException(nameof(byondInstaller));
|
||||
@@ -144,7 +137,7 @@ namespace Tgstation.Server.Host.Components
|
||||
var chat = chatFactory.CreateChat(metadata.ChatSettings);
|
||||
try
|
||||
{
|
||||
var sessionControllerFactory = new SessionControllerFactory(executor, byond, byondTopicSender, cryptographySuite, application, gameIoManager, chat, loggerFactory, metadata.CloneMetadata());
|
||||
var sessionControllerFactory = new SessionControllerFactory(processExecutor, byond, byondTopicSender, cryptographySuite, application, gameIoManager, chat, loggerFactory, metadata.CloneMetadata());
|
||||
var reattachInfoHandler = new ReattachInfoHandler(databaseContextFactory, dmbFactory, metadata.CloneMetadata());
|
||||
var watchdogFactory = new WatchdogFactory(chat, sessionControllerFactory, serverUpdater, loggerFactory, reattachInfoHandler, databaseContextFactory, byondTopicSender, eventConsumer, metadata.CloneMetadata());
|
||||
var watchdog = watchdogFactory.CreateWatchdog(dmbFactory, metadata.DreamDaemonSettings);
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Byond;
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class Executor : IExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IProcessExecutor"/> for the <see cref="Executor"/>
|
||||
/// </summary>
|
||||
readonly IProcessExecutor processExecutor;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="Executor"/>
|
||||
/// </summary>
|
||||
readonly ILogger<Executor> logger;
|
||||
|
||||
/// <summary>
|
||||
/// Change a given <paramref name="securityLevel"/> into the appropriate DreamDaemon command line word
|
||||
/// </summary>
|
||||
/// <param name="securityLevel">The <see cref="DreamDaemonSecurity"/> level to change</param>
|
||||
/// <returns>A <see cref="string"/> representation of the command line parameter</returns>
|
||||
static string SecurityWord(DreamDaemonSecurity securityLevel)
|
||||
{
|
||||
switch (securityLevel)
|
||||
{
|
||||
case DreamDaemonSecurity.Safe:
|
||||
return "safe";
|
||||
case DreamDaemonSecurity.Trusted:
|
||||
return "trusted";
|
||||
case DreamDaemonSecurity.Ultrasafe:
|
||||
return "ultrasafe";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(securityLevel), securityLevel, String.Format(CultureInfo.InvariantCulture, "Bad DreamDaemon security level: {0}", securityLevel));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="Executor"/>
|
||||
/// </summary>
|
||||
/// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
public Executor(IProcessExecutor processExecutor, ILogger<Executor> logger)
|
||||
{
|
||||
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISession AttachToDreamDaemon(int processId, IByondExecutableLock byondLock) => new Session(processExecutor.GetProcess(processId), byondLock);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISession RunDreamDaemon(DreamDaemonLaunchParameters launchParameters, IByondExecutableLock byondLock, IDmbProvider dmbProvider, string parameters, bool useSecondaryPort, bool useSecondaryDirectory)
|
||||
{
|
||||
if (launchParameters == null)
|
||||
throw new ArgumentNullException(nameof(launchParameters));
|
||||
if (byondLock == null)
|
||||
throw new ArgumentNullException(nameof(byondLock));
|
||||
if (dmbProvider == null)
|
||||
throw new ArgumentNullException(nameof(dmbProvider));
|
||||
if (parameters == null)
|
||||
throw new ArgumentNullException(nameof(parameters));
|
||||
|
||||
var fileName = byondLock.DreamDaemonPath;
|
||||
var workingDirectory = useSecondaryDirectory ? dmbProvider.SecondaryDirectory : dmbProvider.PrimaryDirectory;
|
||||
|
||||
var arguments = String.Format(CultureInfo.InvariantCulture, "{0} -port {1} {2}-close -{3} -verbose -public -params \"{4}\"",
|
||||
dmbProvider.DmbName,
|
||||
useSecondaryPort ? launchParameters.SecondaryPort : launchParameters.PrimaryPort,
|
||||
launchParameters.AllowWebClient.Value ? "-webclient " : String.Empty,
|
||||
SecurityWord(launchParameters.SecurityLevel.Value),
|
||||
parameters);
|
||||
|
||||
logger.LogTrace("Running DreamDaemon in {0}: {1} {2}", workingDirectory, fileName, arguments);
|
||||
|
||||
var proc = processExecutor.LaunchProcess(fileName, workingDirectory, arguments);
|
||||
|
||||
return new Session(proc, byondLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Byond;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// For creating <see cref="ISession"/>s
|
||||
/// </summary>
|
||||
interface IExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Run a dream daemon instance
|
||||
/// </summary>
|
||||
/// <param name="launchParameters">The <see cref="DreamDaemonLaunchParameters"/></param>
|
||||
/// <param name="byondLock">The <see cref="IByondExecutableLock"/> for the new <see cref="ISession"/></param>
|
||||
/// <param name="dmbProvider">The <see cref="IDmbProvider"/> for the .dmb to run</param>
|
||||
/// <param name="parameters">The value of the -params command line option</param>
|
||||
/// <param name="useSecondaryPort">If the <see cref="DreamDaemonLaunchParameters.SecondaryPort"/> field of <paramref name="launchParameters"/> should be used</param>
|
||||
/// <param name="useSecondaryDirectory">If the <see cref="IDmbProvider.SecondaryDirectory"/> field of <paramref name="dmbProvider"/> should be used</param>
|
||||
/// <returns>A new <see cref="ISession"/></returns>
|
||||
ISession RunDreamDaemon(DreamDaemonLaunchParameters launchParameters, IByondExecutableLock byondLock, IDmbProvider dmbProvider, string parameters, bool useSecondaryPort, bool useSecondaryDirectory);
|
||||
|
||||
/// <summary>
|
||||
/// Attach to a running instance of DreamDaemon
|
||||
/// </summary>
|
||||
/// <param name="processId">The <see cref="ISession.ProcessId"/></param>
|
||||
/// <param name="byondLock">The <see cref="IByondExecutableLock"/> for the new <see cref="ISession"/></param>
|
||||
/// <returns>A new <see cref="ISession"/></returns>
|
||||
ISession AttachToDreamDaemon(int processId, IByondExecutableLock byondLock);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a dream daemon process
|
||||
/// </summary>
|
||||
interface ISession : ISessionBase, IProcess
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
interface ISessionBase : IProcessBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="Task"/> that completes when DreamDaemon starts pumping the windows message queue after loading a .dmb or when it crashes
|
||||
/// </summary>
|
||||
Task<LaunchResult> LaunchResult { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,26 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles communication with a <see cref="ISession"/>
|
||||
/// Handles communication with a DreamDaemon <see cref="IProcess"/>
|
||||
/// </summary>
|
||||
interface ISessionController : ISessionBase
|
||||
interface ISessionController : IProcessBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="Task"/> that completes when DreamDaemon starts pumping the windows message queue after loading a .dmb or when it crashes
|
||||
/// </summary>
|
||||
Task<LaunchResult> LaunchResult { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="IDmbProvider.PrimaryDirectory"/> of <see cref="Dmb"/> is being used
|
||||
/// </summary>
|
||||
bool IsPrimary { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If the DMAPI was validated. This field may only be access once <see cref="ISessionBase.Lifetime"/> completes
|
||||
/// If the DMAPI was validated. This field may only be access once <see cref="IProcessBase.Lifetime"/> completes
|
||||
/// </summary>
|
||||
bool ApiValidated { get; }
|
||||
|
||||
@@ -44,7 +50,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
Task OnReboot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Releases the <see cref="ISession"/> without terminating it. Also calls <see cref="System.IDisposable.Dispose"/>
|
||||
/// Releases the <see cref="IProcess"/> without terminating it. Also calls <see cref="System.IDisposable.Dispose"/>
|
||||
/// </summary>
|
||||
/// <returns><see cref="ReattachInformation"/> which can be used to create a new <see cref="ISessionController"/> similar to this one</returns>
|
||||
ReattachInformation Release();
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Components.Byond;
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class Session : ISession
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public int Id => process.Id;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task Startup => process.Startup;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<LaunchResult> LaunchResult { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<int> Lifetime => process.Lifetime;
|
||||
|
||||
/// <summary>
|
||||
/// The actual <see cref="IProcess"/>
|
||||
/// </summary>
|
||||
readonly IProcess process;
|
||||
/// <summary>
|
||||
/// The <see cref="IByondExecutableLock"/> for the <see cref="process"/>
|
||||
/// </summary>
|
||||
readonly IByondExecutableLock byondLock;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="Session"/>
|
||||
/// </summary>
|
||||
/// <param name="process">The value of <see cref="process"/></param>
|
||||
/// <param name="byondLock">The value of <see cref="byondLock"/></param>
|
||||
public Session(IProcess process, IByondExecutableLock byondLock)
|
||||
{
|
||||
this.process = process ?? throw new ArgumentNullException(nameof(process));
|
||||
this.byondLock = byondLock ?? throw new ArgumentNullException(nameof(byondLock));
|
||||
|
||||
async Task<LaunchResult> GetLaunchResult()
|
||||
{
|
||||
var startTime = DateTimeOffset.Now;
|
||||
await process.Startup.ConfigureAwait(false);
|
||||
var result = new LaunchResult
|
||||
{
|
||||
ExitCode = process.Lifetime.IsCompleted ? (int?)await process.Lifetime.ConfigureAwait(false) : null,
|
||||
StartupTime = DateTimeOffset.Now - startTime
|
||||
};
|
||||
return result;
|
||||
};
|
||||
LaunchResult = GetLaunchResult();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
process.Dispose();
|
||||
byondLock.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Terminate() => process.Terminate();
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetErrorOutput() => process.GetErrorOutput();
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetStandardOutput() => process.GetStandardOutput();
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCombinedOutput() => process.GetCombinedOutput();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,9 @@ using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Host.Components.Byond;
|
||||
using Tgstation.Server.Host.Components.Chat;
|
||||
using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
@@ -72,10 +74,10 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<LaunchResult> LaunchResult => session.LaunchResult;
|
||||
public Task<LaunchResult> LaunchResult { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<int> Lifetime => session.Lifetime;
|
||||
public Task<int> Lifetime => process.Lifetime;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task OnReboot => rebootTcs.Task;
|
||||
@@ -96,9 +98,14 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
readonly IInteropContext interopContext;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ISession"/> for the <see cref="SessionController"/>
|
||||
/// The <see cref="IProcess"/> for the <see cref="SessionController"/>
|
||||
/// </summary>
|
||||
readonly ISession session;
|
||||
readonly IProcess process;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IByondExecutableLock"/> for the <see cref="SessionController"/>
|
||||
/// </summary>
|
||||
readonly IByondExecutableLock byondLock;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IJsonTrackingContext"/> for the <see cref="SessionController"/>
|
||||
@@ -144,7 +151,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
bool apiValidated;
|
||||
|
||||
/// <summary>
|
||||
/// If <see cref="session"/> should be kept alive instead
|
||||
/// If <see cref="process"/> should be kept alive instead
|
||||
/// </summary>
|
||||
bool released;
|
||||
|
||||
@@ -152,18 +159,20 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// Construct a <see cref="SessionController"/>
|
||||
/// </summary>
|
||||
/// <param name="reattachInformation">The value of <see cref="reattachInformation"/></param>
|
||||
/// <param name="session">The value of <see cref="session"/></param>
|
||||
/// <param name="process">The value of <see cref="process"/></param>
|
||||
/// <param name="byondLock">The value of <see cref="byondLock"/></param>
|
||||
/// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
|
||||
/// <param name="interopContext">The value of <see cref="interopContext"/></param>
|
||||
/// <param name="chat">The value of <see cref="chat"/></param>
|
||||
/// <param name="chatJsonTrackingContext">The value of <see cref="chatJsonTrackingContext"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
public SessionController(ReattachInformation reattachInformation, ISession session, IByondTopicSender byondTopicSender, IJsonTrackingContext chatJsonTrackingContext, IInteropContext interopContext, IChat chat, ILogger<SessionController> logger)
|
||||
public SessionController(ReattachInformation reattachInformation, IProcess process, IByondExecutableLock byondLock, IByondTopicSender byondTopicSender, IJsonTrackingContext chatJsonTrackingContext, IInteropContext interopContext, IChat chat, ILogger<SessionController> logger)
|
||||
{
|
||||
this.chatJsonTrackingContext = chatJsonTrackingContext; //null valid
|
||||
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
|
||||
this.byondTopicSender = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
|
||||
this.session = session ?? throw new ArgumentNullException(nameof(session));
|
||||
this.process = process ?? throw new ArgumentNullException(nameof(process));
|
||||
this.byondLock = byondLock ?? throw new ArgumentNullException(nameof(byondLock));
|
||||
this.interopContext = interopContext ?? throw new ArgumentNullException(nameof(interopContext));
|
||||
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@@ -176,6 +185,19 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
released = false;
|
||||
|
||||
rebootTcs = new TaskCompletionSource<object>();
|
||||
|
||||
async Task<LaunchResult> GetLaunchResult()
|
||||
{
|
||||
var startTime = DateTimeOffset.Now;
|
||||
await process.Startup.ConfigureAwait(false);
|
||||
var result = new LaunchResult
|
||||
{
|
||||
ExitCode = process.Lifetime.IsCompleted ? (int?)await process.Lifetime.ConfigureAwait(false) : null,
|
||||
StartupTime = DateTimeOffset.Now - startTime
|
||||
};
|
||||
return result;
|
||||
};
|
||||
LaunchResult = GetLaunchResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -201,8 +223,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
if (disposing)
|
||||
{
|
||||
if (!released)
|
||||
session.Terminate();
|
||||
session.Dispose();
|
||||
{
|
||||
process.Terminate();
|
||||
byondLock.Dispose();
|
||||
}
|
||||
process.Dispose();
|
||||
interopContext.Dispose();
|
||||
Dmb?.Dispose(); //will be null when released
|
||||
chatJsonTrackingContext.Dispose();
|
||||
@@ -213,8 +238,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
if (logger != null)
|
||||
logger.LogError("Being disposed via finalizer!");
|
||||
if (!released)
|
||||
if (session != null)
|
||||
session.Terminate();
|
||||
if (process != null)
|
||||
process.Terminate();
|
||||
else if (logger != null)
|
||||
logger.LogCritical("Unable to terminate active DreamDaemon session due to finalizer ordering!");
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Byond;
|
||||
using Tgstation.Server.Host.Components.Chat;
|
||||
@@ -21,9 +22,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
sealed class SessionControllerFactory : ISessionControllerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IExecutor"/> for the <see cref="SessionControllerFactory"/>
|
||||
/// The <see cref="IProcessExecutor"/> for the <see cref="SessionControllerFactory"/>
|
||||
/// </summary>
|
||||
readonly IExecutor executor;
|
||||
readonly IProcessExecutor processExecutor;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IByondManager"/> for the <see cref="SessionControllerFactory"/>
|
||||
@@ -65,10 +66,30 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// </summary>
|
||||
readonly Api.Models.Instance instance;
|
||||
|
||||
/// <summary>
|
||||
/// Change a given <paramref name="securityLevel"/> into the appropriate DreamDaemon command line word
|
||||
/// </summary>
|
||||
/// <param name="securityLevel">The <see cref="DreamDaemonSecurity"/> level to change</param>
|
||||
/// <returns>A <see cref="string"/> representation of the command line parameter</returns>
|
||||
static string SecurityWord(DreamDaemonSecurity securityLevel)
|
||||
{
|
||||
switch (securityLevel)
|
||||
{
|
||||
case DreamDaemonSecurity.Safe:
|
||||
return "safe";
|
||||
case DreamDaemonSecurity.Trusted:
|
||||
return "trusted";
|
||||
case DreamDaemonSecurity.Ultrasafe:
|
||||
return "ultrasafe";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(securityLevel), securityLevel, String.Format(CultureInfo.InvariantCulture, "Bad DreamDaemon security level: {0}", securityLevel));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="SessionControllerFactory"/>
|
||||
/// </summary>
|
||||
/// <param name="executor">The value of <see cref="executor"/></param>
|
||||
/// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
|
||||
/// <param name="byond">The value of <see cref="byond"/></param>
|
||||
/// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
|
||||
/// <param name="cryptographySuite">The value of <see cref="cryptographySuite"/></param>
|
||||
@@ -77,9 +98,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/></param>
|
||||
/// <param name="chat">The value of <see cref="chat"/></param>
|
||||
/// <param name="loggerFactory">The value of <see cref="loggerFactory"/></param>
|
||||
public SessionControllerFactory(IExecutor executor, IByondManager byond, IByondTopicSender byondTopicSender, ICryptographySuite cryptographySuite, IApplication application, IIOManager ioManager, IChat chat, ILoggerFactory loggerFactory, Api.Models.Instance instance)
|
||||
public SessionControllerFactory(IProcessExecutor processExecutor, IByondManager byond, IByondTopicSender byondTopicSender, ICryptographySuite cryptographySuite, IApplication application, IIOManager ioManager, IChat chat, ILoggerFactory loggerFactory, Api.Models.Instance instance)
|
||||
{
|
||||
this.executor = executor ?? throw new ArgumentNullException(nameof(executor));
|
||||
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
|
||||
this.byond = byond ?? throw new ArgumentNullException(nameof(byond));
|
||||
this.byondTopicSender = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
|
||||
this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
|
||||
@@ -150,7 +171,14 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
var context = new InteropContext(ioManager, loggerFactory.CreateLogger<InteropContext>(), basePath, interopInfo.ServerCommandsJson);
|
||||
try
|
||||
{
|
||||
var session = executor.RunDreamDaemon(launchParameters, byondLock, dmbProvider, parameters, !primaryPort, !primaryDirectory);
|
||||
var arguments = String.Format(CultureInfo.InvariantCulture, "{0} -port {1} {2}-close -{3} -verbose -public -params \"{4}\"",
|
||||
dmbProvider.DmbName,
|
||||
primaryPort ? launchParameters.PrimaryPort : launchParameters.SecondaryPort,
|
||||
launchParameters.AllowWebClient.Value ? "-webclient " : String.Empty,
|
||||
SecurityWord(launchParameters.SecurityLevel.Value),
|
||||
parameters);
|
||||
|
||||
var process = processExecutor.LaunchProcess(byondLock.DreamDaemonPath, basePath, arguments);
|
||||
try
|
||||
{
|
||||
return new SessionController(new ReattachInformation
|
||||
@@ -159,15 +187,15 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
Dmb = dmbProvider,
|
||||
IsPrimary = primaryDirectory,
|
||||
Port = portToUse.Value,
|
||||
ProcessId = session.Id,
|
||||
ProcessId = process.Id,
|
||||
ChatChannelsJson = interopInfo.ChatChannelsJson,
|
||||
ChatCommandsJson = interopInfo.ChatCommandsJson,
|
||||
ServerCommandsJson = interopInfo.ServerCommandsJson,
|
||||
}, session, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>());
|
||||
}, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
session.Dispose();
|
||||
process.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -207,14 +235,14 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
var context = new InteropContext(ioManager, loggerFactory.CreateLogger<InteropContext>(), basePath, reattachInformation.ServerCommandsJson);
|
||||
try
|
||||
{
|
||||
var session = executor.AttachToDreamDaemon(reattachInformation.ProcessId, byondLock);
|
||||
var process = processExecutor.GetProcess(reattachInformation.ProcessId);
|
||||
try
|
||||
{
|
||||
return new SessionController(reattachInformation, session, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>());
|
||||
return new SessionController(reattachInformation, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
session.Dispose();
|
||||
process.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,6 @@ namespace Tgstation.Server.Host.Core
|
||||
}
|
||||
|
||||
services.AddSingleton<IProcessExecutor, ProcessExecutor>();
|
||||
services.AddSingleton<IExecutor, Executor>();
|
||||
services.AddSingleton<IProviderFactory, ProviderFactory>();
|
||||
services.AddSingleton<IByondTopicSender>(new ByondTopicSender
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user