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