Added online detection handler
This commit is contained in:
@@ -0,0 +1,85 @@
|
|||||||
|
using MoonlightServers.Daemon.ServerSystem.Enums;
|
||||||
|
using MoonlightServers.Daemon.ServerSystem.Interfaces;
|
||||||
|
using MoonlightServers.Daemon.ServerSystem.Models;
|
||||||
|
using Stateless;
|
||||||
|
|
||||||
|
namespace MoonlightServers.Daemon.ServerSystem.Handlers;
|
||||||
|
|
||||||
|
public class OnlineDetectionHandler : IServerStateHandler
|
||||||
|
{
|
||||||
|
private readonly ServerContext Context;
|
||||||
|
private IOnlineDetector OnlineDetector => Context.Server.OnlineDetector;
|
||||||
|
private ILogger Logger => Context.Logger;
|
||||||
|
|
||||||
|
private IAsyncDisposable? ConsoleSubscription;
|
||||||
|
private bool IsActive = false;
|
||||||
|
|
||||||
|
public OnlineDetectionHandler(ServerContext context)
|
||||||
|
{
|
||||||
|
Context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecuteAsync(StateMachine<ServerState, ServerTrigger>.Transition transition)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
transition is
|
||||||
|
{ Source: ServerState.Offline, Destination: ServerState.Starting, Trigger: ServerTrigger.Start } && !IsActive
|
||||||
|
)
|
||||||
|
{
|
||||||
|
await StartAsync();
|
||||||
|
}
|
||||||
|
else if (transition is { Source: not ServerState.Installing, Destination: ServerState.Offline } && IsActive)
|
||||||
|
{
|
||||||
|
await StopAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task StartAsync()
|
||||||
|
{
|
||||||
|
IsActive = true;
|
||||||
|
|
||||||
|
await OnlineDetector.CreateAsync();
|
||||||
|
|
||||||
|
ConsoleSubscription = await Context.Server.Console.SubscribeStdOutAsync(OnHandleOutput);
|
||||||
|
|
||||||
|
Logger.LogTrace("Created online detector. Created console subscription");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ValueTask OnHandleOutput(string line)
|
||||||
|
{
|
||||||
|
if(!IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!await OnlineDetector.HandleOutputAsync(line))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!Context.Server.StateMachine.CanFire(ServerTrigger.DetectOnline))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Logger.LogTrace("Detected server as online. Destroying online detector");
|
||||||
|
|
||||||
|
await Context.Server.StateMachine.FireAsync(ServerTrigger.DetectOnline);
|
||||||
|
await StopAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task StopAsync()
|
||||||
|
{
|
||||||
|
IsActive = false;
|
||||||
|
|
||||||
|
if (ConsoleSubscription != null)
|
||||||
|
{
|
||||||
|
await ConsoleSubscription.DisposeAsync();
|
||||||
|
ConsoleSubscription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await OnlineDetector.DestroyAsync();
|
||||||
|
|
||||||
|
Logger.LogTrace("Destroyed online detector. Revoked console subscription");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
if (ConsoleSubscription != null)
|
||||||
|
await ConsoleSubscription.DisposeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ public class ShutdownHandler : IServerStateHandler
|
|||||||
{
|
{
|
||||||
Destination: ServerState.Offline,
|
Destination: ServerState.Offline,
|
||||||
Source: not ServerState.Installing,
|
Source: not ServerState.Installing,
|
||||||
Trigger: ServerTrigger.Exited
|
Trigger: ServerTrigger.Exited // We don't want to handle the fail event here
|
||||||
})
|
})
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ public class StartupHandler : IServerStateHandler
|
|||||||
// 4. Run file system checks
|
// 4. Run file system checks
|
||||||
// 5. Create runtime
|
// 5. Create runtime
|
||||||
// 6. Attach console
|
// 6. Attach console
|
||||||
// 7. Attach statistics collector
|
// 7. Start runtime
|
||||||
// 8. Create online detector
|
|
||||||
// 9. Start runtime
|
|
||||||
|
|
||||||
// 1. Fetch latest configuration
|
// 1. Fetch latest configuration
|
||||||
// TODO
|
// TODO
|
||||||
|
// Consider moving it out of the startup handler, as other handlers might need
|
||||||
|
// the updated config as well or add sorting into the handler registration to ensure they are executing in the correct order.
|
||||||
|
// Sort when building server, not when executing handlers
|
||||||
|
|
||||||
// 2. Check if file system exists
|
// 2. Check if file system exists
|
||||||
if (!await Server.RuntimeFileSystem.CheckExistsAsync())
|
if (!await Server.RuntimeFileSystem.CheckExistsAsync())
|
||||||
@@ -65,16 +66,7 @@ public class StartupHandler : IServerStateHandler
|
|||||||
|
|
||||||
await Server.Console.AttachRuntimeAsync();
|
await Server.Console.AttachRuntimeAsync();
|
||||||
|
|
||||||
// 7. Attach statistics collector
|
// 7. Start runtime
|
||||||
|
|
||||||
await Server.Statistics.AttachRuntimeAsync();
|
|
||||||
|
|
||||||
// 8. Create online detector
|
|
||||||
|
|
||||||
await Server.OnlineDetector.CreateAsync();
|
|
||||||
await Server.OnlineDetector.DestroyAsync();
|
|
||||||
|
|
||||||
// 9. Start runtime
|
|
||||||
|
|
||||||
await Server.Runtime.StartAsync();
|
await Server.Runtime.StartAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class ServerFactory
|
|||||||
// Resolve handlers
|
// Resolve handlers
|
||||||
var handlers = new List<IServerStateHandler>();
|
var handlers = new List<IServerStateHandler>();
|
||||||
|
|
||||||
|
handlers.Add(ActivatorUtilities.CreateInstance<OnlineDetectionHandler>(scope.ServiceProvider));
|
||||||
handlers.Add(ActivatorUtilities.CreateInstance<StartupHandler>(scope.ServiceProvider));
|
handlers.Add(ActivatorUtilities.CreateInstance<StartupHandler>(scope.ServiceProvider));
|
||||||
handlers.Add(ActivatorUtilities.CreateInstance<ShutdownHandler>(scope.ServiceProvider));
|
handlers.Add(ActivatorUtilities.CreateInstance<ShutdownHandler>(scope.ServiceProvider));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user