Abstract server state to support other engines, add Docker container stats
This commit is contained in:
parent
fd27010a81
commit
425bae360b
7 changed files with 77 additions and 16 deletions
|
|
@ -159,6 +159,8 @@ namespace LANCommander.SDK
|
|||
await terminator.WaitForExitAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Process = null;
|
||||
}
|
||||
|
||||
public async Task ExecuteGameActionAsync(string installDirectory, Guid gameId, Models.Action action, string args = "", CancellationToken cancellationToken = default)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public interface IServerEngine
|
|||
public bool IsManaging(Guid serverId);
|
||||
public Task StartAsync(Guid serverId);
|
||||
public Task StopAsync(Guid serverId);
|
||||
public Task<ServerProcessState> GetStateAsync(Guid serverId);
|
||||
public Task<IServerState> GetStateAsync(Guid serverId);
|
||||
public event EventHandler<ServerStatusUpdateEventArgs> OnServerStatusUpdate;
|
||||
public event EventHandler<ServerLogEventArgs> OnServerLog;
|
||||
}
|
||||
13
LANCommander.Server.Services/Abstractions/IServerState.cs
Normal file
13
LANCommander.Server.Services/Abstractions/IServerState.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System.Diagnostics;
|
||||
using LANCommander.Server.Services.Enums;
|
||||
|
||||
namespace LANCommander.Server.Services.Abstractions;
|
||||
|
||||
public interface IServerState
|
||||
{
|
||||
public ServerProcessStatus Status { get; set; }
|
||||
public ulong MemoryUsage { get; set; }
|
||||
public ulong TotalMemory { get; set; }
|
||||
public double ProcessorLoad { get; set; }
|
||||
public CancellationTokenSource CancellationToken { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System.Diagnostics;
|
||||
using Docker.DotNet;
|
||||
using LANCommander.Server.Services.Abstractions;
|
||||
using LANCommander.Server.Services.Enums;
|
||||
|
||||
namespace LANCommander.Server.Services.Models;
|
||||
|
||||
public class ServerDockerContainerState : IServerState
|
||||
{
|
||||
public ServerProcessStatus Status { get; set; } = ServerProcessStatus.Stopped;
|
||||
public ulong MemoryUsage { get; set; }
|
||||
public ulong TotalMemory { get; set; }
|
||||
public double ProcessorLoad { get; set; }
|
||||
public DockerClient Client { get; set; }
|
||||
public DockerContainer Container { get; set; }
|
||||
public CancellationTokenSource CancellationToken { get; set; } = new();
|
||||
}
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
using System.Diagnostics;
|
||||
using LANCommander.Server.Services.Abstractions;
|
||||
using LANCommander.Server.Services.Enums;
|
||||
|
||||
namespace LANCommander.Server.Services.Models;
|
||||
|
||||
public class ServerProcessState
|
||||
public class ServerProcessState : IServerState
|
||||
{
|
||||
public ServerProcessStatus Status { get; set; } = ServerProcessStatus.Stopped;
|
||||
public long MemoryUsage { get; set; }
|
||||
public ulong MemoryUsage { get; set; }
|
||||
public ulong TotalMemory { get; set; }
|
||||
public double ProcessorLoad { get; set; }
|
||||
public TimeSpan LastMeasuredProcessorTime { get; set; }
|
||||
public Stopwatch ProcessTimer { get; set; } = new();
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ public class DockerServerEngine(
|
|||
SDK.Client client) : IServerEngine
|
||||
{
|
||||
private ServerEngineConfiguration _config;
|
||||
private Dictionary<Guid, ServerDockerContainerState> _state = new();
|
||||
private Dictionary<Guid, DockerClient> _dockerClients = new();
|
||||
private Dictionary<Guid, DockerContainer> _tracked { get; set; } = new();
|
||||
public event EventHandler<ServerStatusUpdateEventArgs>? OnServerStatusUpdate;
|
||||
public event EventHandler<ServerLogEventArgs>? OnServerLog;
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ public class DockerServerEngine(
|
|||
foreach (var server in servers)
|
||||
{
|
||||
if (server.DockerHostId.HasValue && _dockerClients.ContainsKey(server.DockerHostId.Value))
|
||||
_tracked[server.Id] = new DockerContainer
|
||||
_state[server.Id].Container = new DockerContainer
|
||||
{
|
||||
HostId = server.DockerHostId.Value,
|
||||
Id = server.ContainerId,
|
||||
|
|
@ -76,14 +76,14 @@ public class DockerServerEngine(
|
|||
|
||||
public bool IsManaging(Guid serverId)
|
||||
{
|
||||
return _tracked.ContainsKey(serverId);
|
||||
return _state.ContainsKey(serverId);
|
||||
}
|
||||
|
||||
public async Task StartAsync(Guid serverId)
|
||||
{
|
||||
Data.Models.Server server;
|
||||
|
||||
if (!_tracked.ContainsKey(serverId))
|
||||
if (!IsManaging(serverId))
|
||||
throw new Exception("Server is not being tracked by this engine.");
|
||||
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
|
|
@ -141,7 +141,7 @@ public class DockerServerEngine(
|
|||
|
||||
public async Task StopAsync(Guid serverId)
|
||||
{
|
||||
if (!_tracked.ContainsKey(serverId))
|
||||
if (!IsManaging(serverId))
|
||||
throw new Exception("Server is not being tracked by this engine.");
|
||||
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
|
|
@ -182,13 +182,13 @@ public class DockerServerEngine(
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<ServerProcessStatus> GetStatusAsync(Guid serverId)
|
||||
private async Task<ServerProcessStatus> GetStatusAsync(Guid serverId)
|
||||
{
|
||||
Data.Models.Server server = null;
|
||||
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
if (!_tracked.ContainsKey(serverId))
|
||||
if (!IsManaging(serverId))
|
||||
{
|
||||
var serverService = scope.ServiceProvider.GetRequiredService<ServerService>();
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ public class DockerServerEngine(
|
|||
if (String.IsNullOrWhiteSpace(server.ContainerId))
|
||||
return ServerProcessStatus.Stopped;
|
||||
|
||||
_tracked[serverId] = new DockerContainer
|
||||
_state[serverId].Container = new DockerContainer
|
||||
{
|
||||
Id = server.ContainerId,
|
||||
HostId = server.DockerHostId.Value,
|
||||
|
|
@ -213,7 +213,7 @@ public class DockerServerEngine(
|
|||
|
||||
try
|
||||
{
|
||||
var container = await _dockerClients[_tracked[serverId].HostId].Containers.InspectContainerAsync(_tracked[serverId].Id);
|
||||
var container = await _dockerClients[_state[serverId].Container.HostId].Containers.InspectContainerAsync(_state[serverId].Container.Id);
|
||||
|
||||
if (container.State.Running)
|
||||
return ServerProcessStatus.Running;
|
||||
|
|
@ -235,8 +235,35 @@ public class DockerServerEngine(
|
|||
}
|
||||
}
|
||||
|
||||
public Task<ServerProcessState> GetStateAsync(Guid serverId)
|
||||
public async Task<IServerState> GetStateAsync(Guid serverId)
|
||||
{
|
||||
return Task.FromResult(new ServerProcessState());
|
||||
if (!IsManaging(serverId))
|
||||
_state[serverId] = new ServerDockerContainerState();
|
||||
|
||||
var statsProgress = new Progress<ContainerStatsResponse>(stats =>
|
||||
{
|
||||
// Calculate CPU usage
|
||||
var cpuDelta = stats.CPUStats.CPUUsage.TotalUsage - stats.PreCPUStats.CPUUsage.TotalUsage;
|
||||
var systemDelta = stats.CPUStats.SystemUsage - stats.PreCPUStats.SystemUsage;
|
||||
double cpuPercentage = 0;
|
||||
|
||||
if (systemDelta > 0 && cpuDelta > 0)
|
||||
cpuPercentage = ((double)cpuDelta / systemDelta) * stats.CPUStats.OnlineCPUs * 100.0;
|
||||
|
||||
_state[serverId].ProcessorLoad = cpuPercentage;
|
||||
_state[serverId].MemoryUsage = stats.MemoryStats.Usage;
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
_dockerClients[_state[serverId].Container.HostId].Containers.GetContainerStatsAsync(_state[serverId].Container.Id, new ContainerStatsParameters { Stream = false}, statsProgress);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_state[serverId].MemoryUsage = 0;
|
||||
_state[serverId].ProcessorLoad = 0;
|
||||
}
|
||||
|
||||
return await Task.FromResult(_state[serverId]);
|
||||
}
|
||||
}
|
||||
|
|
@ -196,7 +196,7 @@ public class LocalServerEngine(
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<ServerProcessState> GetStateAsync(Guid serverId)
|
||||
public async Task<IServerState> GetStateAsync(Guid serverId)
|
||||
{
|
||||
if (serverId == Guid.Empty)
|
||||
return null!;
|
||||
|
|
@ -208,7 +208,7 @@ public class LocalServerEngine(
|
|||
{
|
||||
_state[serverId].Status = ServerProcessStatus.Running;
|
||||
|
||||
_state[serverId].MemoryUsage = _state[serverId].Process.PrivateMemorySize64;
|
||||
_state[serverId].MemoryUsage = (ulong)_state[serverId].Process.PrivateMemorySize64;
|
||||
_state[serverId].ProcessorLoad = (_state[serverId].Process.TotalProcessorTime - _state[serverId].LastMeasuredProcessorTime).TotalMilliseconds / (Environment.ProcessorCount * _state[serverId].ProcessTimer.ElapsedMilliseconds);
|
||||
|
||||
_state[serverId].ProcessTimer.Restart();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue