163 lines
5.5 KiB
C#
163 lines
5.5 KiB
C#
namespace MoonlightServers.Daemon.ServerSystem;
|
|
|
|
public partial class Server
|
|
{
|
|
public async Task StartAsync()
|
|
{
|
|
await Lock.WaitAsync();
|
|
|
|
try
|
|
{
|
|
if (State != ServerState.Offline)
|
|
throw new InvalidOperationException("Server is not offline");
|
|
|
|
// Check for any pre-existing runtime environment, if we don't have a reference already
|
|
RuntimeEnvironment ??= await RuntimeEnvironmentService.FindAsync(Uuid);
|
|
RuntimeStorage ??= await RuntimeStorageService.FindAsync(Uuid);
|
|
|
|
// Remove any pre-existing environment
|
|
if (RuntimeEnvironment != null)
|
|
{
|
|
Logger.LogTrace("Destroying pre-existing runtime environment");
|
|
|
|
if (await RuntimeEnvironment.IsRunningAsync())
|
|
{
|
|
Logger.LogTrace("Pre-existing runtime environment is still running, killing it");
|
|
await RuntimeEnvironment.KillAsync();
|
|
}
|
|
|
|
// Make sure no event handler is there anymore
|
|
RuntimeEnvironment.Console.OnOutput -= OnConsoleMessageAsync;
|
|
RuntimeEnvironment.Statistics.OnStatisticsReceived -= OnStatisticsReceivedAsync;
|
|
RuntimeEnvironment.OnExited -= OnRuntimeExitedAsync;
|
|
|
|
// Finally remove it
|
|
await RuntimeEnvironmentService.DeleteAsync(RuntimeEnvironment);
|
|
RuntimeEnvironment = null;
|
|
|
|
Logger.LogTrace("Pre-existing runtime environment destroyed");
|
|
}
|
|
|
|
// Fetch the latest config
|
|
Logger.LogTrace("Fetching latest configuration");
|
|
RuntimeConfiguration = await ConfigurationService.GetRuntimeConfigurationAsync(Uuid);
|
|
|
|
// Ensure runtime storage
|
|
if (RuntimeStorage == null)
|
|
{
|
|
Logger.LogTrace("Creating runtime storage");
|
|
RuntimeStorage = await RuntimeStorageService.CreateAsync(Uuid, RuntimeConfiguration);
|
|
}
|
|
else
|
|
{
|
|
Logger.LogTrace("Updating runtime storage");
|
|
await RuntimeStorageService.UpdateAsync(RuntimeStorage, RuntimeConfiguration);
|
|
}
|
|
|
|
// Create the environment
|
|
Logger.LogTrace("Creating runtime environment");
|
|
|
|
RuntimeEnvironment = await RuntimeEnvironmentService.CreateAsync(Uuid, RuntimeConfiguration, RuntimeStorage);
|
|
|
|
// Set event handlers
|
|
Logger.LogTrace("Attaching to runtime environment");
|
|
|
|
RuntimeEnvironment.Console.OnOutput += OnConsoleMessageAsync;
|
|
RuntimeEnvironment.Statistics.OnStatisticsReceived += OnStatisticsReceivedAsync;
|
|
RuntimeEnvironment.OnExited += OnRuntimeExitedAsync;
|
|
|
|
// Attach console & statistics
|
|
await RuntimeEnvironment.Console.AttachAsync();
|
|
await RuntimeEnvironment.Statistics.AttachAsync();
|
|
|
|
// Start up
|
|
Logger.LogTrace("Starting runtime environment");
|
|
|
|
await RuntimeEnvironment.StartAsync();
|
|
|
|
await ChangeStateAsync(ServerState.Starting);
|
|
}
|
|
finally
|
|
{
|
|
Lock.Release();
|
|
}
|
|
}
|
|
|
|
public async Task StopAsync()
|
|
{
|
|
await Lock.WaitAsync();
|
|
|
|
try
|
|
{
|
|
if (State is not (ServerState.Starting or ServerState.Online))
|
|
throw new InvalidOperationException("Server is not starting or online");
|
|
|
|
if (RuntimeEnvironment == null)
|
|
throw new InvalidOperationException("Runtime environment is not set");
|
|
|
|
Logger.LogTrace("Sending stop command to runtime environment");
|
|
await RuntimeEnvironment.Console.WriteInputAsync("stop\n\r");
|
|
|
|
await ChangeStateAsync(ServerState.Stopping);
|
|
}
|
|
finally
|
|
{
|
|
Lock.Release();
|
|
}
|
|
}
|
|
|
|
public async Task KillAsync()
|
|
{
|
|
await Lock.WaitAsync();
|
|
|
|
try
|
|
{
|
|
if (State is not (ServerState.Starting or ServerState.Online or ServerState.Stopping))
|
|
throw new InvalidOperationException("Server is not starting, stopping or online");
|
|
|
|
if (RuntimeEnvironment == null)
|
|
throw new InvalidOperationException("Runtime environment is not set");
|
|
|
|
Logger.LogTrace("Killing runtime environment");
|
|
await RuntimeEnvironment.KillAsync();
|
|
|
|
await ChangeStateAsync(ServerState.Stopping);
|
|
}
|
|
finally
|
|
{
|
|
Lock.Release();
|
|
}
|
|
}
|
|
|
|
private async Task OnRuntimeExitedAsync()
|
|
{
|
|
Logger.LogTrace("Runtime environment exited, checking result and cleaning up");
|
|
|
|
await Lock.WaitAsync();
|
|
|
|
try
|
|
{
|
|
// TODO: Handle crash
|
|
|
|
if (RuntimeEnvironment == null)
|
|
throw new InvalidOperationException("Runtime environment is not set");
|
|
|
|
// Make sure no event handler is there anymore
|
|
RuntimeEnvironment.Console.OnOutput -= OnConsoleMessageAsync;
|
|
RuntimeEnvironment.Statistics.OnStatisticsReceived -= OnStatisticsReceivedAsync;
|
|
RuntimeEnvironment.OnExited -= OnRuntimeExitedAsync;
|
|
|
|
// Finally remove it
|
|
await RuntimeEnvironmentService.DeleteAsync(RuntimeEnvironment);
|
|
RuntimeEnvironment = null;
|
|
|
|
Logger.LogTrace("Runtime environment cleaned up");
|
|
}
|
|
finally
|
|
{
|
|
Lock.Release();
|
|
}
|
|
|
|
await ChangeStateAsync(ServerState.Offline);
|
|
}
|
|
} |