Fix deadlock with DumpOnHealthCheckRestart

This commit is contained in:
Jordan Dominion
2023-12-03 14:53:45 -05:00
parent 69f4c7e0b6
commit da78b8e8a1
@@ -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);
}
}
}