Update Remora.Discord

This commit is contained in:
Jordan Dominion
2023-07-24 20:08:04 -04:00
parent c79f12c2dc
commit a8ca804f86
2 changed files with 2 additions and 52 deletions
@@ -3,9 +3,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
@@ -19,7 +17,6 @@ using Remora.Discord.API.Abstractions.Results;
using Remora.Discord.API.Objects;
using Remora.Discord.Gateway;
using Remora.Discord.Gateway.Extensions;
using Remora.Discord.Gateway.Services;
using Remora.Rest.Core;
using Remora.Rest.Results;
using Remora.Results;
@@ -227,54 +224,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
await base.DisposeAsync();
// https://github.com/Remora/Remora.Discord/issues/305
var responderDispatchService = serviceProvider.GetRequiredService<ResponderDispatchService>();
var serviceProviderDisposeTask = serviceProvider.DisposeAsync().AsTask();
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);
var dispatcherCompleted = dispatcherTask.IsCompleted;
var finalizerCompleted = finalizerTask.IsCompleted;
if (dispatcherCompleted && !finalizerCompleted)
{
// deadlocked, force close the channel
var channel = (Channel<Task<IReadOnlyList<Result>>>)responderDispatchServiceType.GetField("_respondersToFinalize", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(responderDispatchService);
if (!channel.Writer.TryComplete())
Logger.LogCritical("Workaround failed (channel already closed), you may be deadlocked!");
else
{
// drain the channel, fuck the results
// DCT: None available
await foreach (var result in channel.Reader.ReadAllAsync(CancellationToken.None))
try
{
await result;
}
catch (Exception ex)
{
Logger.LogDebug(ex, "Channel draining exception!");
}
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;
await serviceProvider.DisposeAsync();
Logger.LogTrace("ServiceProvider disposed");
@@ -95,7 +95,7 @@
<!-- Usage: MYSQL/MariaDB ORM plugin -->
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
<!-- Usage: Discord interop -->
<PackageReference Include="Remora.Discord" Version="2023.3.0" />
<PackageReference Include="Remora.Discord" Version="2023.4.0" />
<!-- Usage: Rich logger builder -->
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<!-- Usage: Async logging plugin -->