diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index aae40a9c6..0edb93c95 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -9,6 +9,7 @@ Current package versions: ## Unreleased - Fix logic inversion with `ARGREP NOCASE`, add `IsReversed` to simplify ordering, and support `ARINFO FULL`. ([#3087 by @mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/3087)) +- Avoid sentinel issues if `ROLE` unavailable; fix #3064 ([#3088 by @mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/3088)) ## 2.13.10 diff --git a/src/StackExchange.Redis/ConnectionMultiplexer.Sentinel.cs b/src/StackExchange.Redis/ConnectionMultiplexer.Sentinel.cs index 61b36b014..35276347d 100644 --- a/src/StackExchange.Redis/ConnectionMultiplexer.Sentinel.cs +++ b/src/StackExchange.Redis/ConnectionMultiplexer.Sentinel.cs @@ -240,10 +240,28 @@ public ConnectionMultiplexer GetSentinelMasterConnection(ConfigurationOptions co // verify role is primary according to: // https://redis.io/topics/sentinel-clients - if (connection.GetServer(newPrimaryEndPoint)?.Role()?.Value == RedisLiterals.master) + bool isPrimary; + var server = connection.GetServer(newPrimaryEndPoint); + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + if (server is { }) { - success = true; - break; + try + { + isPrimary = connection.CommandMap.IsAvailable(RedisCommand.ROLE) + ? server.Role()?.Value == RedisLiterals.master + : !server.IsReplica; + } + catch + { + // fallback if ROLE unavailable but not declared; see #3064 + isPrimary = !server.IsReplica; + } + + if (isPrimary) + { + success = true; + break; + } } Thread.Sleep(100);