From 322c7044d3a056c150099be09b5aa638987a48c8 Mon Sep 17 00:00:00 2001 From: Nick Craver Date: Tue, 10 Sep 2024 11:54:47 -0400 Subject: [PATCH] Always perform "last read" check in heartbeat when HeartbeatConsistencyChecks is enabled (#2795) When we have slowly adding things to the heartbeat (originally intended just to send data to keep connections alive) like detecting connection health, the if/else has gotten more complicated. With the addition of HeartbeatConsistencyChecks, we prevented some fall throughs to later checks which means that if that option is enabled, we were no longer detecting dead sockets as intended. This is a tactical fix for the combination, but I think overall we should look at refactoring how this entire method works because shoehorning these things into the original structure/purpose has been problematic several times. --- docs/ReleaseNotes.md | 3 ++- src/StackExchange.Redis/PhysicalBridge.cs | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 9dff1c3e0..74fb39034 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -7,7 +7,8 @@ Current package versions: | [![StackExchange.Redis](https://img.shields.io/nuget/v/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/vpre/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis MyGet](https://img.shields.io/myget/stackoverflow/vpre/StackExchange.Redis.svg)](https://www.myget.org/feed/stackoverflow/package/nuget/StackExchange.Redis) | ## Unreleased -No pending unreleased changes. + +- Fix: PhysicalBridge: Always perform "last read" check in heartbeat when `HeartbeatConsistencyChecks` is enabled ([#2795 by NickCraver](https://github.com/StackExchange/StackExchange.Redis/pull/2795)) ## 2.8.14 diff --git a/src/StackExchange.Redis/PhysicalBridge.cs b/src/StackExchange.Redis/PhysicalBridge.cs index 6cc8aa6f6..e063233b5 100644 --- a/src/StackExchange.Redis/PhysicalBridge.cs +++ b/src/StackExchange.Redis/PhysicalBridge.cs @@ -652,7 +652,9 @@ internal void OnHeartbeat(bool ifConnectedOnly) // so if we have an empty unsent queue and a non-empty sent queue, test the socket. KeepAlive(); } - else if (timedOutThisHeartbeat > 0 + + // This is an "always" check - we always want to evaluate a dead connection from a non-responsive sever regardless of the need to heartbeat above + if (timedOutThisHeartbeat > 0 && tmp.LastReadSecondsAgo * 1_000 > (tmp.BridgeCouldBeNull?.Multiplexer.AsyncTimeoutMilliseconds * 4)) { // If we've received *NOTHING* on the pipe in 4 timeouts worth of time and we're timing out commands, issue a connection failure so that we reconnect