Files
Servers/MoonlightServers.Daemon/ServerSystem/Implementations/Docker/DockerEventService.cs

93 lines
2.6 KiB
C#

using Docker.DotNet;
using Docker.DotNet.Models;
using MoonlightServers.Daemon.ServerSystem.Implementations.Docker.Events;
namespace MoonlightServers.Daemon.ServerSystem.Implementations.Docker;
public class DockerEventService : BackgroundService
{
public event Func<ContainerDieEvent, Task>? OnContainerDied;
private readonly ILogger<DockerEventService> Logger;
private readonly DockerClient DockerClient;
public DockerEventService(
ILogger<DockerEventService> logger,
DockerClient dockerClient
)
{
Logger = logger;
DockerClient = dockerClient;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Logger.LogTrace("Starting up docker event monitor");
while (!stoppingToken.IsCancellationRequested)
{
try
{
Logger.LogTrace("Monitoring events");
await DockerClient.System.MonitorEventsAsync(
new ContainerEventsParameters(),
new Progress<Message>(OnEventAsync),
stoppingToken
);
}
catch (OperationCanceledException)
{
// ignored
}
catch (Exception e)
{
Logger.LogError(e, "An error occured while processing container event monitoring");
}
}
Logger.LogTrace("Closed docker event monitor");
}
private async void OnEventAsync(Message message)
{
try
{
switch (message.Type)
{
case "container":
var containerId = message.Actor.ID;
switch (message.Action)
{
case "die":
if (
!message.Actor.Attributes.TryGetValue("exitCode", out var exitCodeStr) ||
!int.TryParse(exitCodeStr, out var exitCode)
)
{
return;
}
if (OnContainerDied != null)
await OnContainerDied.Invoke(new ContainerDieEvent(containerId, exitCode));
return;
}
break;
}
}
catch (Exception e)
{
Logger.LogError(
e,
"An error occured while handling event {type} for {action}",
message.Type,
message.Action
);
}
}
}