mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-04-22 19:15:48 +02:00
Replace remaining uses of TaskManager
This commit is contained in:
parent
94148add2d
commit
137a2a53c3
Agent/Phantom.Agent.Services
Controller/Phantom.Controller
Utils/Phantom.Utils/Tasks
Web/Phantom.Web
@ -6,7 +6,6 @@ using Phantom.Agent.Services.Instances;
|
||||
using Phantom.Common.Data.Agent;
|
||||
using Phantom.Utils.Actor;
|
||||
using Phantom.Utils.Logging;
|
||||
using Phantom.Utils.Tasks;
|
||||
using Serilog;
|
||||
|
||||
namespace Phantom.Agent.Services;
|
||||
@ -18,7 +17,6 @@ public sealed class AgentServices {
|
||||
|
||||
private AgentFolders AgentFolders { get; }
|
||||
private AgentState AgentState { get; }
|
||||
private TaskManager TaskManager { get; }
|
||||
private BackupManager BackupManager { get; }
|
||||
|
||||
internal JavaRuntimeRepository JavaRuntimeRepository { get; }
|
||||
@ -30,13 +28,12 @@ public sealed class AgentServices {
|
||||
|
||||
this.AgentFolders = agentFolders;
|
||||
this.AgentState = new AgentState();
|
||||
this.TaskManager = new TaskManager(PhantomLogger.Create<TaskManager, AgentServices>());
|
||||
this.BackupManager = new BackupManager(agentFolders, serviceConfiguration.MaxConcurrentCompressionTasks);
|
||||
|
||||
this.JavaRuntimeRepository = new JavaRuntimeRepository();
|
||||
this.InstanceTicketManager = new InstanceTicketManager(agentInfo, controllerConnection);
|
||||
|
||||
var instanceManagerInit = new InstanceManagerActor.Init(controllerConnection, agentFolders, AgentState, JavaRuntimeRepository, InstanceTicketManager, TaskManager, BackupManager);
|
||||
var instanceManagerInit = new InstanceManagerActor.Init(controllerConnection, agentFolders, AgentState, JavaRuntimeRepository, InstanceTicketManager, BackupManager);
|
||||
this.InstanceManager = ActorSystem.ActorOf(InstanceManagerActor.Factory(instanceManagerInit), "InstanceManager");
|
||||
}
|
||||
|
||||
@ -50,7 +47,6 @@ public sealed class AgentServices {
|
||||
Logger.Information("Stopping services...");
|
||||
|
||||
await InstanceManager.Stop(new InstanceManagerActor.ShutdownCommand());
|
||||
await TaskManager.Stop();
|
||||
|
||||
BackupManager.Dispose();
|
||||
|
||||
|
@ -24,7 +24,7 @@ sealed class BackupScheduler : CancellableBackgroundTask {
|
||||
|
||||
public event EventHandler<BackupCreationResult>? BackupCompleted;
|
||||
|
||||
public BackupScheduler(InstanceContext context, InstanceProcess process, int serverPort) : base(PhantomLogger.Create<BackupScheduler>(context.ShortName), context.Services.TaskManager, "Backup scheduler for " + context.ShortName) {
|
||||
public BackupScheduler(InstanceContext context, InstanceProcess process, int serverPort) : base(PhantomLogger.Create<BackupScheduler>(context.ShortName)) {
|
||||
this.backupManager = context.Services.BackupManager;
|
||||
this.context = context;
|
||||
this.process = process;
|
||||
|
@ -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 InstanceTicketManager, BackupManager BackupManager);
|
||||
|
||||
public static Props<ICommand> Factory(Init init) {
|
||||
return Props<ICommand>.Create(() => new InstanceManagerActor(init), new ActorConfiguration { SupervisorStrategy = SupervisorStrategies.Resume });
|
||||
@ -47,7 +47,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
||||
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.BackupManager, launchServices);
|
||||
|
||||
ReceiveAndReply<ConfigureInstanceCommand, InstanceActionResult<ConfigureInstanceResult>>(ConfigureInstance);
|
||||
ReceiveAndReply<LaunchInstanceCommand, InstanceActionResult<LaunchInstanceResult>>(LaunchInstance);
|
||||
|
@ -1,8 +1,7 @@
|
||||
using Phantom.Agent.Minecraft.Launcher;
|
||||
using Phantom.Agent.Rpc;
|
||||
using Phantom.Agent.Services.Backups;
|
||||
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, BackupManager BackupManager, LaunchServices LaunchServices);
|
||||
|
@ -22,7 +22,7 @@ sealed class InstanceLogSender : CancellableBackgroundTask {
|
||||
|
||||
private int droppedLinesSinceLastSend;
|
||||
|
||||
public InstanceLogSender(ControllerConnection controllerConnection, TaskManager taskManager, Guid instanceGuid, string loggerName) : base(PhantomLogger.Create<InstanceLogSender>(loggerName), taskManager, "Instance log sender for " + loggerName) {
|
||||
public InstanceLogSender(ControllerConnection controllerConnection, Guid instanceGuid, string loggerName) : base(PhantomLogger.Create<InstanceLogSender>(loggerName)) {
|
||||
this.controllerConnection = controllerConnection;
|
||||
this.instanceGuid = instanceGuid;
|
||||
this.outputChannel = Channel.CreateBounded<string>(BufferOptions, OnLineDropped);
|
||||
|
@ -31,7 +31,7 @@ sealed class InstanceRunningState : IDisposable {
|
||||
this.Process = process;
|
||||
this.cancellationToken = cancellationToken;
|
||||
|
||||
this.logSender = new InstanceLogSender(context.Services.ControllerConnection, context.Services.TaskManager, context.InstanceGuid, context.ShortName);
|
||||
this.logSender = new InstanceLogSender(context.Services.ControllerConnection, context.InstanceGuid, context.ShortName);
|
||||
|
||||
this.backupScheduler = new BackupScheduler(context, process, configuration.ServerPort);
|
||||
this.backupScheduler.BackupCompleted += OnScheduledBackupCompleted;
|
||||
|
@ -10,7 +10,6 @@ using Phantom.Utils.Logging;
|
||||
using Phantom.Utils.Rpc;
|
||||
using Phantom.Utils.Rpc.Runtime;
|
||||
using Phantom.Utils.Runtime;
|
||||
using Phantom.Utils.Tasks;
|
||||
|
||||
var shutdownCancellationTokenSource = new CancellationTokenSource();
|
||||
var shutdownCancellationToken = shutdownCancellationTokenSource.Token;
|
||||
@ -64,14 +63,12 @@ try {
|
||||
return new RpcConfiguration(serviceName, host, port, connectionKey.Certificate);
|
||||
}
|
||||
|
||||
var rpcTaskManager = new TaskManager(PhantomLogger.Create<TaskManager>("Rpc"));
|
||||
try {
|
||||
await Task.WhenAll(
|
||||
RpcServerRuntime.Launch(ConfigureRpc("Agent", agentRpcServerHost, agentRpcServerPort, agentKeyData), AgentMessageRegistries.Definitions, controllerServices.AgentRegistrationHandler, controllerServices.ActorSystem, shutdownCancellationToken),
|
||||
RpcServerRuntime.Launch(ConfigureRpc("Web", webRpcServerHost, webRpcServerPort, webKeyData), WebMessageRegistries.Definitions, controllerServices.WebRegistrationHandler, controllerServices.ActorSystem, shutdownCancellationToken)
|
||||
);
|
||||
} finally {
|
||||
await rpcTaskManager.Stop();
|
||||
NetMQConfig.Cleanup();
|
||||
}
|
||||
|
||||
|
@ -8,19 +8,13 @@ public abstract class CancellableBackgroundTask {
|
||||
protected ILogger Logger { get; }
|
||||
protected CancellationToken CancellationToken { get; }
|
||||
|
||||
private readonly TaskManager taskManager;
|
||||
private readonly string taskName;
|
||||
|
||||
protected CancellableBackgroundTask(ILogger logger, TaskManager taskManager, string taskName) {
|
||||
protected CancellableBackgroundTask(ILogger logger) {
|
||||
this.Logger = logger;
|
||||
this.CancellationToken = cancellationTokenSource.Token;
|
||||
|
||||
this.taskManager = taskManager;
|
||||
this.taskName = taskName;
|
||||
}
|
||||
|
||||
protected void Start() {
|
||||
taskManager.Run(taskName, Run);
|
||||
Task.Run(Run, CancellationToken.None);
|
||||
}
|
||||
|
||||
private async Task Run() {
|
||||
|
@ -1,76 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Phantom.Utils.Collections;
|
||||
using Serilog;
|
||||
|
||||
namespace Phantom.Utils.Tasks;
|
||||
|
||||
public sealed class TaskManager {
|
||||
private readonly ILogger logger;
|
||||
private readonly CancellationTokenSource cancellationTokenSource = new ();
|
||||
private readonly CancellationToken cancellationToken;
|
||||
|
||||
private readonly ConcurrentDictionary<Task, string> runningTasks = new (ReferenceEqualityComparer<Task>.Instance);
|
||||
|
||||
public TaskManager(ILogger logger) {
|
||||
this.logger = logger;
|
||||
this.cancellationToken = cancellationTokenSource.Token;
|
||||
}
|
||||
|
||||
private T Add<T>(string name, T task) where T : Task {
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
runningTasks.TryAdd(task, name);
|
||||
task.ContinueWith(OnFinished, CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously, TaskScheduler.Default);
|
||||
return task;
|
||||
}
|
||||
|
||||
private void OnFinished(Task task) {
|
||||
runningTasks.TryRemove(task, out _);
|
||||
}
|
||||
|
||||
public Task Run(string name, Action action) {
|
||||
return Add(name, Task.Run(action, cancellationToken));
|
||||
}
|
||||
|
||||
public Task Run(string name, Func<Task> taskFunc) {
|
||||
return Add(name, Task.Run(taskFunc, cancellationToken));
|
||||
}
|
||||
|
||||
public Task<T> Run<T>(string name, Func<Task<T>> taskFunc) {
|
||||
return Add(name, Task.Run(taskFunc, cancellationToken));
|
||||
}
|
||||
|
||||
public async Task Stop() {
|
||||
logger.Information("Stopping task manager...");
|
||||
|
||||
cancellationTokenSource.Cancel();
|
||||
|
||||
var remainingTasksAwaiterTask = WaitForRemainingTasks();
|
||||
while (true) {
|
||||
var logStateTimeoutTask = Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None);
|
||||
var completedTask = await Task.WhenAny(remainingTasksAwaiterTask, logStateTimeoutTask);
|
||||
if (completedTask == logStateTimeoutTask) {
|
||||
var remainingTaskNames = runningTasks.Values.Order().ToList();
|
||||
var remainingTaskNameList = string.Join('\n', remainingTaskNames.Select(static name => "- " + name));
|
||||
logger.Warning("Waiting for {TaskCount} task(s) to finish:\n{TaskNames}", remainingTaskNames.Count, remainingTaskNameList);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
runningTasks.Clear();
|
||||
cancellationTokenSource.Dispose();
|
||||
|
||||
logger.Information("Task manager stopped.");
|
||||
}
|
||||
|
||||
private async Task WaitForRemainingTasks() {
|
||||
foreach (var task in runningTasks.Keys) {
|
||||
try {
|
||||
await task;
|
||||
} catch (Exception) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ using Phantom.Utils.Logging;
|
||||
using Phantom.Utils.Rpc;
|
||||
using Phantom.Utils.Rpc.Sockets;
|
||||
using Phantom.Utils.Runtime;
|
||||
using Phantom.Utils.Tasks;
|
||||
using Phantom.Web;
|
||||
using Phantom.Web.Services;
|
||||
using Phantom.Web.Services.Rpc;
|
||||
@ -59,8 +58,7 @@ try {
|
||||
var rpcSocket = RpcClientSocket.Connect(rpcConfiguration, WebMessageRegistries.Definitions, new RegisterWebMessage(webToken));
|
||||
|
||||
var webConfiguration = new WebLauncher.Configuration(PhantomLogger.Create("Web"), webServerHost, webServerPort, webBasePath, dataProtectionKeysPath, shutdownCancellationToken);
|
||||
var taskManager = new TaskManager(PhantomLogger.Create<TaskManager>("Web"));
|
||||
var webApplication = WebLauncher.CreateApplication(webConfiguration, taskManager, applicationProperties, rpcSocket.Connection);
|
||||
var webApplication = WebLauncher.CreateApplication(webConfiguration, applicationProperties, rpcSocket.Connection);
|
||||
|
||||
using var actorSystem = ActorSystemFactory.Create("Web");
|
||||
|
||||
@ -88,7 +86,6 @@ try {
|
||||
await WebLauncher.Launch(webConfiguration, webApplication);
|
||||
} finally {
|
||||
shutdownCancellationTokenSource.Cancel();
|
||||
await taskManager.Stop();
|
||||
|
||||
rpcDisconnectSemaphore.Release();
|
||||
await rpcTask;
|
||||
|
@ -1,7 +1,6 @@
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Phantom.Common.Messages.Web;
|
||||
using Phantom.Utils.Rpc.Runtime;
|
||||
using Phantom.Utils.Tasks;
|
||||
using Phantom.Web.Services;
|
||||
using Serilog;
|
||||
using ILogger = Serilog.ILogger;
|
||||
@ -13,7 +12,7 @@ static class WebLauncher {
|
||||
public string HttpUrl => "http://" + Host + ":" + Port;
|
||||
}
|
||||
|
||||
internal static WebApplication CreateApplication(Configuration config, TaskManager taskManager, ApplicationProperties applicationProperties, RpcConnectionToServer<IMessageToController> controllerConnection) {
|
||||
internal static WebApplication CreateApplication(Configuration config, ApplicationProperties applicationProperties, RpcConnectionToServer<IMessageToController> controllerConnection) {
|
||||
var assembly = typeof(WebLauncher).Assembly;
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
|
||||
ApplicationName = assembly.GetName().Name,
|
||||
@ -29,7 +28,6 @@ static class WebLauncher {
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
}
|
||||
|
||||
builder.Services.AddSingleton(taskManager);
|
||||
builder.Services.AddSingleton(applicationProperties);
|
||||
builder.Services.AddSingleton(controllerConnection);
|
||||
builder.Services.AddPhantomServices();
|
||||
|
Loading…
Reference in New Issue
Block a user