mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2024-11-25 07:42:58 +01:00
Compare commits
2 Commits
df4b64cf8d
...
c171feaf1c
Author | SHA1 | Date | |
---|---|---|---|
c171feaf1c | |||
b6fdb55719 |
@ -59,7 +59,7 @@ sealed class BackupScheduler : CancellableBackgroundTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await context.Actor.Request(new InstanceActor.BackupInstanceCommand(backupManager, CancellationToken));
|
return await context.Actor.Request(new InstanceActor.BackupInstanceCommand(backupManager));
|
||||||
} finally {
|
} finally {
|
||||||
backupSemaphore.Release();
|
backupSemaphore.Release();
|
||||||
}
|
}
|
||||||
|
@ -13,28 +13,32 @@ using Phantom.Utils.Logging;
|
|||||||
namespace Phantom.Agent.Services.Instances;
|
namespace Phantom.Agent.Services.Instances;
|
||||||
|
|
||||||
sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
||||||
public readonly record struct Init(Guid InstanceGuid, string ShortName, InstanceServices Services, AgentState AgentState);
|
public readonly record struct Init(AgentState AgentState, Guid InstanceGuid, string ShortName, InstanceServices InstanceServices, InstanceTicketManager InstanceTicketManager, CancellationToken ShutdownCancellationToken);
|
||||||
|
|
||||||
public static Props<ICommand> Factory(Init init) {
|
public static Props<ICommand> Factory(Init init) {
|
||||||
return Props<ICommand>.Create(() => new InstanceActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume, MailboxType = UnboundedJumpAheadMailbox.Name });
|
return Props<ICommand>.Create(() => new InstanceActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume, MailboxType = UnboundedJumpAheadMailbox.Name });
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Guid instanceGuid;
|
|
||||||
private readonly InstanceServices services;
|
|
||||||
private readonly AgentState agentState;
|
private readonly AgentState agentState;
|
||||||
|
private readonly CancellationToken shutdownCancellationToken;
|
||||||
|
|
||||||
|
private readonly Guid instanceGuid;
|
||||||
|
private readonly InstanceServices instanceServices;
|
||||||
|
private readonly InstanceTicketManager instanceTicketManager;
|
||||||
private readonly InstanceContext context;
|
private readonly InstanceContext context;
|
||||||
|
|
||||||
private IInstanceStatus currentStatus = InstanceStatus.NotRunning;
|
private IInstanceStatus currentStatus = InstanceStatus.NotRunning;
|
||||||
private InstanceRunningState? runningState = null;
|
private InstanceRunningState? runningState = null;
|
||||||
|
|
||||||
private InstanceActor(Init init) {
|
private InstanceActor(Init init) {
|
||||||
this.instanceGuid = init.InstanceGuid;
|
|
||||||
this.services = init.Services;
|
|
||||||
this.agentState = init.AgentState;
|
this.agentState = init.AgentState;
|
||||||
|
this.instanceGuid = init.InstanceGuid;
|
||||||
|
this.instanceServices = init.InstanceServices;
|
||||||
|
this.instanceTicketManager = init.InstanceTicketManager;
|
||||||
|
this.shutdownCancellationToken = init.ShutdownCancellationToken;
|
||||||
|
|
||||||
var logger = PhantomLogger.Create<InstanceActor>(init.ShortName);
|
var logger = PhantomLogger.Create<InstanceActor>(init.ShortName);
|
||||||
this.context = new InstanceContext(instanceGuid, init.ShortName, logger, services, SelfTyped);
|
this.context = new InstanceContext(instanceGuid, init.ShortName, logger, instanceServices, SelfTyped);
|
||||||
|
|
||||||
Receive<ReportInstanceStatusCommand>(ReportInstanceStatus);
|
Receive<ReportInstanceStatusCommand>(ReportInstanceStatus);
|
||||||
ReceiveAsync<LaunchInstanceCommand>(LaunchInstance);
|
ReceiveAsync<LaunchInstanceCommand>(LaunchInstance);
|
||||||
@ -52,7 +56,7 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
|
|
||||||
private void ReportCurrentStatus() {
|
private void ReportCurrentStatus() {
|
||||||
agentState.UpdateInstance(new Instance(instanceGuid, currentStatus));
|
agentState.UpdateInstance(new Instance(instanceGuid, currentStatus));
|
||||||
services.ControllerConnection.Send(new ReportInstanceStatusMessage(instanceGuid, currentStatus));
|
instanceServices.ControllerConnection.Send(new ReportInstanceStatusMessage(instanceGuid, currentStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TransitionState(InstanceRunningState? newState) {
|
private void TransitionState(InstanceRunningState? newState) {
|
||||||
@ -60,10 +64,6 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runningState is not null && newState is null) {
|
|
||||||
context.Services.InstanceTicketManager.Release(runningState.Ticket);
|
|
||||||
}
|
|
||||||
|
|
||||||
runningState?.Dispose();
|
runningState?.Dispose();
|
||||||
runningState = newState;
|
runningState = newState;
|
||||||
runningState?.Initialize();
|
runningState?.Initialize();
|
||||||
@ -73,13 +73,13 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
|
|
||||||
public sealed record ReportInstanceStatusCommand : ICommand;
|
public sealed record ReportInstanceStatusCommand : ICommand;
|
||||||
|
|
||||||
public sealed record LaunchInstanceCommand(InstanceConfiguration Configuration, IServerLauncher Launcher, InstanceTicketManager.Ticket Ticket, bool IsRestarting, CancellationToken CancellationToken) : ICommand;
|
public sealed record LaunchInstanceCommand(InstanceConfiguration Configuration, IServerLauncher Launcher, InstanceTicketManager.Ticket Ticket, bool IsRestarting) : ICommand;
|
||||||
|
|
||||||
public sealed record StopInstanceCommand(MinecraftStopStrategy StopStrategy, CancellationToken CancellationToken) : ICommand;
|
public sealed record StopInstanceCommand(MinecraftStopStrategy StopStrategy) : ICommand;
|
||||||
|
|
||||||
public sealed record SendCommandToInstanceCommand(string Command, CancellationToken CancellationToken) : ICommand, ICanReply<SendCommandToInstanceResult>;
|
public sealed record SendCommandToInstanceCommand(string Command) : ICommand, ICanReply<SendCommandToInstanceResult>;
|
||||||
|
|
||||||
public sealed record BackupInstanceCommand(BackupManager BackupManager, CancellationToken CancellationToken) : ICommand, ICanReply<BackupCreationResult>;
|
public sealed record BackupInstanceCommand(BackupManager BackupManager) : ICommand, ICanReply<BackupCreationResult>;
|
||||||
|
|
||||||
public sealed record HandleProcessEndedCommand(IInstanceStatus Status) : ICommand, IJumpAhead;
|
public sealed record HandleProcessEndedCommand(IInstanceStatus Status) : ICommand, IJumpAhead;
|
||||||
|
|
||||||
@ -93,9 +93,9 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
if (command.IsRestarting || runningState is null) {
|
if (command.IsRestarting || runningState is null) {
|
||||||
SetAndReportStatus(command.IsRestarting ? InstanceStatus.Restarting : InstanceStatus.Launching);
|
SetAndReportStatus(command.IsRestarting ? InstanceStatus.Restarting : InstanceStatus.Launching);
|
||||||
|
|
||||||
var newState = await InstanceLaunchProcedure.Run(context, command.Configuration, command.Launcher, command.Ticket, SetAndReportStatus, command.CancellationToken);
|
var newState = await InstanceLaunchProcedure.Run(context, command.Configuration, command.Launcher, instanceTicketManager, command.Ticket, SetAndReportStatus, shutdownCancellationToken);
|
||||||
if (newState is null) {
|
if (newState is null) {
|
||||||
context.Services.InstanceTicketManager.Release(command.Ticket);
|
instanceTicketManager.Release(command.Ticket);
|
||||||
}
|
}
|
||||||
|
|
||||||
TransitionState(newState);
|
TransitionState(newState);
|
||||||
@ -110,7 +110,8 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
IInstanceStatus oldStatus = currentStatus;
|
IInstanceStatus oldStatus = currentStatus;
|
||||||
SetAndReportStatus(InstanceStatus.Stopping);
|
SetAndReportStatus(InstanceStatus.Stopping);
|
||||||
|
|
||||||
if (await InstanceStopProcedure.Run(context, command.StopStrategy, runningState, SetAndReportStatus, command.CancellationToken)) {
|
if (await InstanceStopProcedure.Run(context, command.StopStrategy, runningState, SetAndReportStatus, shutdownCancellationToken)) {
|
||||||
|
instanceTicketManager.Release(runningState.Ticket);
|
||||||
TransitionState(null);
|
TransitionState(null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -123,7 +124,7 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
return SendCommandToInstanceResult.InstanceNotRunning;
|
return SendCommandToInstanceResult.InstanceNotRunning;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return await runningState.SendCommand(command.Command, command.CancellationToken);
|
return await runningState.SendCommand(command.Command, shutdownCancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +133,7 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
return new BackupCreationResult(BackupCreationResultKind.InstanceNotRunning);
|
return new BackupCreationResult(BackupCreationResultKind.InstanceNotRunning);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return await command.BackupManager.CreateBackup(context.ShortName, runningState.Process, command.CancellationToken);
|
return await command.BackupManager.CreateBackup(context.ShortName, runningState.Process, shutdownCancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,12 +141,13 @@ sealed class InstanceActor : ReceiveActor<InstanceActor.ICommand> {
|
|||||||
if (runningState is { Process.HasEnded: true }) {
|
if (runningState is { Process.HasEnded: true }) {
|
||||||
SetAndReportStatus(command.Status);
|
SetAndReportStatus(command.Status);
|
||||||
context.ReportEvent(InstanceEvent.Stopped);
|
context.ReportEvent(InstanceEvent.Stopped);
|
||||||
|
instanceTicketManager.Release(runningState.Ticket);
|
||||||
TransitionState(null);
|
TransitionState(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Shutdown(ShutdownCommand command) {
|
private async Task Shutdown(ShutdownCommand command) {
|
||||||
await StopInstance(new StopInstanceCommand(MinecraftStopStrategy.Instant, CancellationToken.None));
|
await StopInstance(new StopInstanceCommand(MinecraftStopStrategy.Instant));
|
||||||
Context.Stop(Self);
|
Context.Stop(Self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace Phantom.Agent.Services.Instances;
|
|||||||
sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand> {
|
sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand> {
|
||||||
private static readonly ILogger Logger = PhantomLogger.Create<InstanceManagerActor>();
|
private static readonly ILogger Logger = PhantomLogger.Create<InstanceManagerActor>();
|
||||||
|
|
||||||
public readonly record struct Init(ControllerConnection ControllerConnection, AgentFolders AgentFolders, AgentState AgentState, JavaRuntimeRepository JavaRuntimeRepository, InstanceTicketManager TicketManager, TaskManager TaskManager, BackupManager BackupManager);
|
public readonly record struct Init(ControllerConnection ControllerConnection, AgentFolders AgentFolders, AgentState AgentState, JavaRuntimeRepository JavaRuntimeRepository, InstanceTicketManager InstanceTicketManager, TaskManager TaskManager, BackupManager BackupManager);
|
||||||
|
|
||||||
public static Props<ICommand> Factory(Init init) {
|
public static Props<ICommand> Factory(Init init) {
|
||||||
return Props<ICommand>.Create(() => new InstanceManagerActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume });
|
return Props<ICommand>.Create(() => new InstanceManagerActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume });
|
||||||
@ -30,6 +30,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
private readonly string basePath;
|
private readonly string basePath;
|
||||||
|
|
||||||
private readonly InstanceServices instanceServices;
|
private readonly InstanceServices instanceServices;
|
||||||
|
private readonly InstanceTicketManager instanceTicketManager;
|
||||||
private readonly Dictionary<Guid, InstanceInfo> instances = new ();
|
private readonly Dictionary<Guid, InstanceInfo> instances = new ();
|
||||||
|
|
||||||
private readonly CancellationTokenSource shutdownCancellationTokenSource = new ();
|
private readonly CancellationTokenSource shutdownCancellationTokenSource = new ();
|
||||||
@ -40,12 +41,13 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
private InstanceManagerActor(Init init) {
|
private InstanceManagerActor(Init init) {
|
||||||
this.agentState = init.AgentState;
|
this.agentState = init.AgentState;
|
||||||
this.basePath = init.AgentFolders.InstancesFolderPath;
|
this.basePath = init.AgentFolders.InstancesFolderPath;
|
||||||
|
this.instanceTicketManager = init.InstanceTicketManager;
|
||||||
this.shutdownCancellationToken = shutdownCancellationTokenSource.Token;
|
this.shutdownCancellationToken = shutdownCancellationTokenSource.Token;
|
||||||
|
|
||||||
var minecraftServerExecutables = new MinecraftServerExecutables(init.AgentFolders.ServerExecutableFolderPath);
|
var minecraftServerExecutables = new MinecraftServerExecutables(init.AgentFolders.ServerExecutableFolderPath);
|
||||||
var launchServices = new LaunchServices(minecraftServerExecutables, init.JavaRuntimeRepository);
|
var launchServices = new LaunchServices(minecraftServerExecutables, init.JavaRuntimeRepository);
|
||||||
|
|
||||||
this.instanceServices = new InstanceServices(init.ControllerConnection, init.TaskManager, init.TicketManager, init.BackupManager, launchServices);
|
this.instanceServices = new InstanceServices(init.ControllerConnection, init.TaskManager, init.BackupManager, launchServices);
|
||||||
|
|
||||||
ReceiveAndReply<ConfigureInstanceCommand, InstanceActionResult<ConfigureInstanceResult>>(ConfigureInstance);
|
ReceiveAndReply<ConfigureInstanceCommand, InstanceActionResult<ConfigureInstanceResult>>(ConfigureInstance);
|
||||||
ReceiveAndReply<LaunchInstanceCommand, InstanceActionResult<LaunchInstanceResult>>(LaunchInstance);
|
ReceiveAndReply<LaunchInstanceCommand, InstanceActionResult<LaunchInstanceResult>>(LaunchInstance);
|
||||||
@ -116,7 +118,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var instanceInit = new InstanceActor.Init(instanceGuid, GetInstanceLoggerName(instanceGuid), instanceServices, agentState);
|
var instanceInit = new InstanceActor.Init(agentState, instanceGuid, GetInstanceLoggerName(instanceGuid), instanceServices, instanceTicketManager, shutdownCancellationToken);
|
||||||
instances[instanceGuid] = instance = new InstanceInfo(Context.ActorOf(InstanceActor.Factory(instanceInit), "Instance-" + instanceGuid), configuration, launcher);
|
instances[instanceGuid] = instance = new InstanceInfo(Context.ActorOf(InstanceActor.Factory(instanceInit), "Instance-" + instanceGuid), configuration, launcher);
|
||||||
|
|
||||||
Logger.Information("Created instance \"{Name}\" (GUID {Guid}).", configuration.InstanceName, instanceGuid);
|
Logger.Information("Created instance \"{Name}\" (GUID {Guid}).", configuration.InstanceName, instanceGuid);
|
||||||
@ -137,7 +139,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
return InstanceActionResult.General<LaunchInstanceResult>(InstanceActionGeneralResult.InstanceDoesNotExist);
|
return InstanceActionResult.General<LaunchInstanceResult>(InstanceActionGeneralResult.InstanceDoesNotExist);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ticket = instanceServices.InstanceTicketManager.Reserve(instanceInfo.Configuration);
|
var ticket = instanceTicketManager.Reserve(instanceInfo.Configuration);
|
||||||
if (ticket is Result<InstanceTicketManager.Ticket, LaunchInstanceResult>.Fail fail) {
|
if (ticket is Result<InstanceTicketManager.Ticket, LaunchInstanceResult>.Fail fail) {
|
||||||
return InstanceActionResult.Concrete(fail.Error);
|
return InstanceActionResult.Concrete(fail.Error);
|
||||||
}
|
}
|
||||||
@ -153,7 +155,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO report status?
|
// TODO report status?
|
||||||
instanceInfo.Actor.Tell(new InstanceActor.LaunchInstanceCommand(instanceInfo.Configuration, instanceInfo.Launcher, ticket.Value, IsRestarting: false, shutdownCancellationToken));
|
instanceInfo.Actor.Tell(new InstanceActor.LaunchInstanceCommand(instanceInfo.Configuration, instanceInfo.Launcher, ticket.Value, IsRestarting: false));
|
||||||
return InstanceActionResult.Concrete(LaunchInstanceResult.LaunchInitiated);
|
return InstanceActionResult.Concrete(LaunchInstanceResult.LaunchInitiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +175,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceInfo.Actor.Tell(new InstanceActor.StopInstanceCommand(command.StopStrategy, shutdownCancellationToken));
|
instanceInfo.Actor.Tell(new InstanceActor.StopInstanceCommand(command.StopStrategy));
|
||||||
return InstanceActionResult.Concrete(StopInstanceResult.StopInitiated);
|
return InstanceActionResult.Concrete(StopInstanceResult.StopInitiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +186,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return InstanceActionResult.Concrete(await instanceInfo.Actor.Request(new InstanceActor.SendCommandToInstanceCommand(command.Command, shutdownCancellationToken), shutdownCancellationToken));
|
return InstanceActionResult.Concrete(await instanceInfo.Actor.Request(new InstanceActor.SendCommandToInstanceCommand(command.Command), shutdownCancellationToken));
|
||||||
} catch (OperationCanceledException) {
|
} catch (OperationCanceledException) {
|
||||||
return InstanceActionResult.General<SendCommandToInstanceResult>(InstanceActionGeneralResult.AgentShuttingDown);
|
return InstanceActionResult.General<SendCommandToInstanceResult>(InstanceActionGeneralResult.AgentShuttingDown);
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,4 @@ using Phantom.Utils.Tasks;
|
|||||||
|
|
||||||
namespace Phantom.Agent.Services.Instances;
|
namespace Phantom.Agent.Services.Instances;
|
||||||
|
|
||||||
sealed record InstanceServices(ControllerConnection ControllerConnection, TaskManager TaskManager, InstanceTicketManager InstanceTicketManager, BackupManager BackupManager, LaunchServices LaunchServices);
|
sealed record InstanceServices(ControllerConnection ControllerConnection, TaskManager TaskManager, BackupManager BackupManager, LaunchServices LaunchServices);
|
||||||
|
@ -7,12 +7,12 @@ using Phantom.Utils.Tasks;
|
|||||||
namespace Phantom.Agent.Services.Instances.State;
|
namespace Phantom.Agent.Services.Instances.State;
|
||||||
|
|
||||||
static class InstanceLaunchProcedure {
|
static class InstanceLaunchProcedure {
|
||||||
public static async Task<InstanceRunningState?> Run(InstanceContext context, InstanceConfiguration configuration, IServerLauncher launcher, InstanceTicketManager.Ticket ticket, Action<IInstanceStatus> reportStatus, CancellationToken cancellationToken) {
|
public static async Task<InstanceRunningState?> Run(InstanceContext context, InstanceConfiguration configuration, IServerLauncher launcher, InstanceTicketManager ticketManager, InstanceTicketManager.Ticket ticket, Action<IInstanceStatus> reportStatus, CancellationToken cancellationToken) {
|
||||||
context.Logger.Information("Session starting...");
|
context.Logger.Information("Session starting...");
|
||||||
|
|
||||||
Result<InstanceProcess, InstanceLaunchFailReason> result;
|
Result<InstanceProcess, InstanceLaunchFailReason> result;
|
||||||
|
|
||||||
if (context.Services.InstanceTicketManager.IsValid(ticket)) {
|
if (ticketManager.IsValid(ticket)) {
|
||||||
try {
|
try {
|
||||||
result = await LaunchInstance(context, launcher, reportStatus, cancellationToken);
|
result = await LaunchInstance(context, launcher, reportStatus, cancellationToken);
|
||||||
} catch (OperationCanceledException) {
|
} catch (OperationCanceledException) {
|
||||||
|
@ -72,7 +72,7 @@ sealed class InstanceRunningState : IDisposable {
|
|||||||
else {
|
else {
|
||||||
context.Logger.Information("Session ended unexpectedly, restarting...");
|
context.Logger.Information("Session ended unexpectedly, restarting...");
|
||||||
context.ReportEvent(InstanceEvent.Crashed);
|
context.ReportEvent(InstanceEvent.Crashed);
|
||||||
context.Actor.Tell(new InstanceActor.LaunchInstanceCommand(configuration, launcher, Ticket, IsRestarting: true, cancellationToken));
|
context.Actor.Tell(new InstanceActor.LaunchInstanceCommand(configuration, launcher, Ticket, IsRestarting: true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,8 @@ static class InstanceStopProcedure {
|
|||||||
// Ignore.
|
// Ignore.
|
||||||
} catch (ObjectDisposedException e) when (e.ObjectName == typeof(Process).FullName && process.HasEnded) {
|
} catch (ObjectDisposedException e) when (e.ObjectName == typeof(Process).FullName && process.HasEnded) {
|
||||||
// Ignore.
|
// Ignore.
|
||||||
|
} catch (IOException e) when (e.HResult == -2147024664 /* The pipe is being closed */) {
|
||||||
|
// Ignore.
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
context.Logger.Warning(e, "Caught exception while sending stop command.");
|
context.Logger.Warning(e, "Caught exception while sending stop command.");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user