mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-23 13:07:07 +01:00
Fix deadlock with DumpOnHealthCheckRestart
This commit is contained in:
@@ -446,29 +446,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <inheritdoc />
|
||||
public async ValueTask CreateDump(CancellationToken cancellationToken)
|
||||
{
|
||||
const string DumpDirectory = "ProcessDumps";
|
||||
using (await SemaphoreSlimContext.Lock(synchronizationSemaphore, cancellationToken))
|
||||
{
|
||||
var dumpFileNameTemplate = diagnosticsIOManager.ResolvePath(
|
||||
diagnosticsIOManager.ConcatPath(
|
||||
DumpDirectory,
|
||||
$"DreamDaemon-{DateTimeOffset.UtcNow.ToFileStamp()}.dmp"));
|
||||
|
||||
var dumpFileName = dumpFileNameTemplate;
|
||||
var iteration = 0;
|
||||
while (await diagnosticsIOManager.FileExists(dumpFileName, cancellationToken))
|
||||
dumpFileName = $"{dumpFileNameTemplate} ({++iteration})";
|
||||
|
||||
if (iteration == 0)
|
||||
await diagnosticsIOManager.CreateDirectory(DumpDirectory, cancellationToken);
|
||||
|
||||
var session = GetActiveController();
|
||||
if (session?.Lifetime.IsCompleted != false)
|
||||
throw new JobException(ErrorCode.GameServerOffline);
|
||||
|
||||
Logger.LogInformation("Dumping session to {dumpFileName}...", dumpFileName);
|
||||
await session.CreateDump(dumpFileName, cancellationToken);
|
||||
}
|
||||
await CreateDumpNoLock(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -1153,7 +1132,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
Logger.LogDebug("DumpOnHealthCheckRestart enabled.");
|
||||
try
|
||||
{
|
||||
await CreateDump(cancellationToken);
|
||||
await CreateDumpNoLock(cancellationToken);
|
||||
}
|
||||
catch (JobException ex)
|
||||
{
|
||||
@@ -1203,5 +1182,34 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
.Where(nullableChannelId => nullableChannelId.HasValue)
|
||||
.Select(nullableChannelId => nullableChannelId.Value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to create a process dump for the game server. Requires a lock on <see cref="synchronizationSemaphore"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask CreateDumpNoLock(CancellationToken cancellationToken)
|
||||
{
|
||||
const string DumpDirectory = "ProcessDumps";
|
||||
var dumpFileNameTemplate = diagnosticsIOManager.ResolvePath(
|
||||
diagnosticsIOManager.ConcatPath(
|
||||
DumpDirectory,
|
||||
$"DreamDaemon-{DateTimeOffset.UtcNow.ToFileStamp()}.dmp"));
|
||||
|
||||
var dumpFileName = dumpFileNameTemplate;
|
||||
var iteration = 0;
|
||||
while (await diagnosticsIOManager.FileExists(dumpFileName, cancellationToken))
|
||||
dumpFileName = $"{dumpFileNameTemplate} ({++iteration})";
|
||||
|
||||
if (iteration == 0)
|
||||
await diagnosticsIOManager.CreateDirectory(DumpDirectory, cancellationToken);
|
||||
|
||||
var session = GetActiveController();
|
||||
if (session?.Lifetime.IsCompleted != false)
|
||||
throw new JobException(ErrorCode.GameServerOffline);
|
||||
|
||||
Logger.LogInformation("Dumping session to {dumpFileName}...", dumpFileName);
|
||||
await session.CreateDump(dumpFileName, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user