From 6b4d51426fbc97ce628df3d26f3572dd85a646ca Mon Sep 17 00:00:00 2001 From: felk Date: Thu, 29 Feb 2024 21:50:19 +0100 Subject: [PATCH] fix ungraceful shutdown of EventSub websocket connection --- TPP.Core/Program.cs | 1 + TPP.Twitch.EventSub/EventSubClient.cs | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/TPP.Core/Program.cs b/TPP.Core/Program.cs index 04306ec9..3f83d8a1 100644 --- a/TPP.Core/Program.cs +++ b/TPP.Core/Program.cs @@ -195,6 +195,7 @@ private static void Mode(string modeName, string baseConfigFilename, string mode Task modeTask = mode.Start(cts.Token); void Abort(object? sender, EventArgs args) { + if (cts.IsCancellationRequested) return; logger.LogInformation("Aborting mode..."); cts.Cancel(); cleanupDone.Task.Wait(); diff --git a/TPP.Twitch.EventSub/EventSubClient.cs b/TPP.Twitch.EventSub/EventSubClient.cs index 76a0ef2c..a0b8d6bd 100644 --- a/TPP.Twitch.EventSub/EventSubClient.cs +++ b/TPP.Twitch.EventSub/EventSubClient.cs @@ -121,7 +121,9 @@ public async Task ConnectAndReceive(CancellationToken cancella Instant lastMessageTimestamp = _clock.GetCurrentInstant(); // treat a fresh connection as a received message while (!cancellationToken.IsCancellationRequested) { - Task readTask = ReadMessage(webSocketBox.WebSocket, cancellationToken); + // Don't pass the cancellation token here. Instead, once cancelled we perform a graceful websocket closure. + // Otherwise the websocket would be immediately put in an aborted state, but we're not in that of a hurry. + Task readTask = ReadMessage(webSocketBox.WebSocket, CancellationToken.None); Instant assumeDeadAt = lastMessageTimestamp + KeepaliveDuration + KeepAliveGrace; Instant now = _clock.GetCurrentInstant(); Task timeoutTask = assumeDeadAt < now @@ -215,7 +217,10 @@ public async Task ConnectAndReceive(CancellationToken cancella _logger.LogError("Known message was not handled and skipped: {Message}", message); } } - await webSocketBox.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None); + if (webSocketBox.WebSocket.State == WebSocketState.Open) + await webSocketBox.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None); + else + webSocketBox.WebSocket.Abort(); throw new TaskCanceledException(); }