mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-05-08 12:34:03 +02:00
Change online player check in backup scheduler to wait for any server process output before retrying
This commit is contained in:
parent
b3104f9ac3
commit
09e7510358
Agent/Phantom.Agent.Services/Backups
Utils/Phantom.Utils.Runtime
@ -55,7 +55,7 @@ sealed partial class BackupManager {
|
||||
|
||||
public async Task<BackupCreationResult> CreateBackup() {
|
||||
logger.Information("Backup started.");
|
||||
session.AddOutputListener(listener.OnOutput, 0);
|
||||
session.AddOutputListener(listener.OnOutput, maxLinesToReadFromHistory: 0);
|
||||
try {
|
||||
var resultBuilder = new BackupCreationResult.Builder();
|
||||
|
||||
|
@ -11,13 +11,13 @@ sealed class BackupScheduler : CancellableBackgroundTask {
|
||||
private static readonly TimeSpan InitialDelay = TimeSpan.FromMinutes(2);
|
||||
private static readonly TimeSpan BackupInterval = TimeSpan.FromMinutes(30);
|
||||
private static readonly TimeSpan BackupFailureRetryDelay = TimeSpan.FromMinutes(5);
|
||||
private static readonly TimeSpan OnlinePlayersCheckInterval = TimeSpan.FromMinutes(1);
|
||||
|
||||
private readonly string loggerName;
|
||||
private readonly BackupManager backupManager;
|
||||
private readonly InstanceSession session;
|
||||
private readonly int serverPort;
|
||||
private readonly ServerStatusProtocol serverStatusProtocol;
|
||||
private readonly ManualResetEventSlim serverOutputWhileWaitingForOnlinePlayers = new ();
|
||||
|
||||
public BackupScheduler(TaskManager taskManager, BackupManager backupManager, InstanceSession session, int serverPort, string loggerName) : base(PhantomLogger.Create<BackupScheduler>(loggerName), taskManager, "Backup scheduler for " + loggerName) {
|
||||
this.loggerName = loggerName;
|
||||
@ -52,24 +52,41 @@ sealed class BackupScheduler : CancellableBackgroundTask {
|
||||
private async Task WaitForOnlinePlayers() {
|
||||
bool needsToLogOfflinePlayersMessage = true;
|
||||
|
||||
while (!CancellationToken.IsCancellationRequested) {
|
||||
var onlinePlayerCount = await serverStatusProtocol.GetOnlinePlayerCount(serverPort, CancellationToken);
|
||||
if (onlinePlayerCount == null) {
|
||||
Logger.Warning("Could not detect whether any players are online, starting a new backup.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (onlinePlayerCount > 0) {
|
||||
Logger.Information("Players are online, starting a new backup.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (needsToLogOfflinePlayersMessage) {
|
||||
needsToLogOfflinePlayersMessage = false;
|
||||
Logger.Information("No players are online, waiting for someone to join before starting a new backup.");
|
||||
}
|
||||
session.AddOutputListener(ServerOutputListener, maxLinesToReadFromHistory: 0);
|
||||
try {
|
||||
while (!CancellationToken.IsCancellationRequested) {
|
||||
serverOutputWhileWaitingForOnlinePlayers.Reset();
|
||||
|
||||
var onlinePlayerCount = await serverStatusProtocol.GetOnlinePlayerCount(serverPort, CancellationToken);
|
||||
if (onlinePlayerCount == null) {
|
||||
Logger.Warning("Could not detect whether any players are online, starting a new backup.");
|
||||
break;
|
||||
}
|
||||
|
||||
await Task.Delay(OnlinePlayersCheckInterval, CancellationToken);
|
||||
if (onlinePlayerCount > 0) {
|
||||
Logger.Information("Players are online, starting a new backup.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (needsToLogOfflinePlayersMessage) {
|
||||
needsToLogOfflinePlayersMessage = false;
|
||||
Logger.Information("No players are online, waiting for someone to join before starting a new backup.");
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(10), CancellationToken);
|
||||
|
||||
Logger.Verbose("Waiting for server output before checking for online players again...");
|
||||
await serverOutputWhileWaitingForOnlinePlayers.WaitHandle.WaitOneAsync(CancellationToken);
|
||||
}
|
||||
} finally {
|
||||
session.RemoveOutputListener(ServerOutputListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerOutputListener(object? sender, string line) {
|
||||
if (!serverOutputWhileWaitingForOnlinePlayers.IsSet) {
|
||||
serverOutputWhileWaitingForOnlinePlayers.Set();
|
||||
Logger.Verbose("Detected server output, signalling to check for online players again.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
Utils/Phantom.Utils.Runtime/WaitHandleExtensions.cs
Normal file
27
Utils/Phantom.Utils.Runtime/WaitHandleExtensions.cs
Normal file
@ -0,0 +1,27 @@
|
||||
namespace Phantom.Utils.Runtime;
|
||||
|
||||
public static class WaitHandleExtensions {
|
||||
public static Task WaitOneAsync(this WaitHandle waitHandle, CancellationToken cancellationToken = default) {
|
||||
var taskCompletionSource = new TaskCompletionSource();
|
||||
|
||||
void SetResult(object? state, bool timedOut) {
|
||||
taskCompletionSource.TrySetResult();
|
||||
}
|
||||
|
||||
void SetCancelled() {
|
||||
taskCompletionSource.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
var waitRegistration = ThreadPool.RegisterWaitForSingleObject(waitHandle, SetResult, null, Timeout.InfiniteTimeSpan, true);
|
||||
var tokenRegistration = cancellationToken.Register(SetCancelled, useSynchronizationContext: false);
|
||||
|
||||
void Cleanup(Task t) {
|
||||
waitRegistration.Unregister(null);
|
||||
tokenRegistration.Dispose();
|
||||
}
|
||||
|
||||
var task = taskCompletionSource.Task;
|
||||
task.ContinueWith(Cleanup, CancellationToken.None);
|
||||
return task;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user