From 7fd744f9dc7cebd2ef4ad061e7d9746342904e01 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 3 Jun 2023 01:37:05 -0400 Subject: [PATCH] Longer workaround delay, additional logging --- .../Chat/Providers/DiscordProvider.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index c06ac872c6..478a93a4b2 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -234,23 +234,34 @@ namespace Tgstation.Server.Host.Components.Chat.Providers // https://github.com/Remora/Remora.Discord/issues/305 var responderDispatchService = serviceProvider.GetRequiredService(); var serviceProviderDisposeTask = serviceProvider.DisposeAsync().AsTask(); - var timeout = AsyncDelayer.Delay(TimeSpan.FromSeconds(5), default); // DCT: None available + var timeout = AsyncDelayer.Delay(TimeSpan.FromSeconds(10), default); // DCT: None available await Task.WhenAny(timeout, serviceProviderDisposeTask); if (!serviceProviderDisposeTask.IsCompleted) { // HACK HACK HACK, there's a potential deadlock in the ResponderDispatchService + Logger.LogWarning("ServiceProvider disposal stalled. Attempting workaround..."); var responderDispatchServiceType = responderDispatchService.GetType(); var dispatcherTask = (Task)responderDispatchServiceType.GetField("_dispatcher", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(responderDispatchService); var finalizerTask = (Task)responderDispatchServiceType.GetField("_finalizer", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(responderDispatchService); - if (dispatcherTask.IsCompleted && !finalizerTask.IsCompleted) + var dispatcherCompleted = dispatcherTask.IsCompleted; + var finalizerCompleted = finalizerTask.IsCompleted; + if (dispatcherCompleted && !finalizerCompleted) { // deadlocked, force close the channel var channel = (Channel>>)responderDispatchServiceType.GetField("_respondersToFinalize", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(responderDispatchService); - channel.Writer.TryComplete(); + if (!channel.Writer.TryComplete()) + Logger.LogCritical("Workaround failed (channel already closed), you may be deadlocked!"); + else + Logger.LogInformation("Workaround seems successful. Awaiting ServiceProvider disposal..."); } + else + Logger.LogCritical( + "Workaround failed (_dispatcher: {dispatcherCompleted}, _finalizer: {finalizerCompleted}), you may be deadlocked!", + dispatcherCompleted, + finalizerCompleted); } await serviceProviderDisposeTask;