From 11eb4808bccbf3c1645fe703671029ba90203015 Mon Sep 17 00:00:00 2001 From: Ivan Tikhonov Date: Sat, 29 Aug 2026 10:58:47 +0300 Subject: [PATCH 1/4] add Dragonfly --- src/StackExchange.Redis/AutoConfigureInfoField.cs | 5 ++++- src/StackExchange.Redis/Enums/ProductVariant.cs | 7 ++++++- src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt | 1 + src/StackExchange.Redis/ResultProcessor.cs | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/StackExchange.Redis/AutoConfigureInfoField.cs b/src/StackExchange.Redis/AutoConfigureInfoField.cs index 7420bb02f6..e18d0738b3 100644 --- a/src/StackExchange.Redis/AutoConfigureInfoField.cs +++ b/src/StackExchange.Redis/AutoConfigureInfoField.cs @@ -1,4 +1,4 @@ -using System; +using System; using RESPite; namespace StackExchange.Redis; @@ -38,6 +38,9 @@ internal enum AutoConfigureInfoField [AsciiHash("valkey_version")] ValkeyVersion, + [AsciiHash("dragonfly_version")] + DragonflyVersion, + [AsciiHash("server_mode")] ServerMode, } diff --git a/src/StackExchange.Redis/Enums/ProductVariant.cs b/src/StackExchange.Redis/Enums/ProductVariant.cs index 9355af0731..be20b16530 100644 --- a/src/StackExchange.Redis/Enums/ProductVariant.cs +++ b/src/StackExchange.Redis/Enums/ProductVariant.cs @@ -1,4 +1,4 @@ -// ReSharper disable once CheckNamespace +// ReSharper disable once CheckNamespace namespace StackExchange.Redis; /// @@ -24,5 +24,10 @@ public enum ProductVariant /// Garnet, + /// + /// Dragonfly + /// + Dragonfly, + // if you want to add another variant here, please open an issue with the details (variant name, INFO output, etc.) } diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt index 605f04040e..ad375aa6f4 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt @@ -2322,6 +2322,7 @@ StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Garnet = 2 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Redis = 0 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Valkey = 1 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Dragonfly = 3 -> StackExchange.Redis.ProductVariant static StackExchange.Redis.RedisChannel.SubKeyEvent(StackExchange.Redis.KeyNotificationType type, int? database = null) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeyEvent(System.ReadOnlySpan type, int? database) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeySpaceEvent(StackExchange.Redis.KeyNotificationType type, in StackExchange.Redis.RedisKey key, int? database = null) -> StackExchange.Redis.RedisChannel diff --git a/src/StackExchange.Redis/ResultProcessor.cs b/src/StackExchange.Redis/ResultProcessor.cs index 2175294e8e..692c4fa724 100644 --- a/src/StackExchange.Redis/ResultProcessor.cs +++ b/src/StackExchange.Redis/ResultProcessor.cs @@ -995,6 +995,10 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes productVariant = ProductVariant.Valkey; productVersion = valSpan.ToString(); break; + case AutoConfigureInfoField.DragonflyVersion: + productVariant = ProductVariant.Dragonfly; + productVersion = valSpan.ToString(); + break; } } if (roleSeen && Format.TryParseEndPoint(primaryHost!, primaryPort, out var sep)) From f7decaecdca695f3c1f5a2ba6f272fc40e6b50d2 Mon Sep 17 00:00:00 2001 From: Ivan Tikhonov Date: Wed, 2 Sep 2026 16:59:54 +0300 Subject: [PATCH 2/4] add Memurai and Redict to ProductVariant --- src/StackExchange.Redis/AutoConfigureInfoField.cs | 6 ++++++ src/StackExchange.Redis/Enums/ProductVariant.cs | 10 ++++++++++ .../PublicAPI/PublicAPI.Shipped.txt | 2 ++ src/StackExchange.Redis/ResultProcessor.cs | 8 ++++++++ 4 files changed, 26 insertions(+) diff --git a/src/StackExchange.Redis/AutoConfigureInfoField.cs b/src/StackExchange.Redis/AutoConfigureInfoField.cs index e18d0738b3..5e0c579bfe 100644 --- a/src/StackExchange.Redis/AutoConfigureInfoField.cs +++ b/src/StackExchange.Redis/AutoConfigureInfoField.cs @@ -41,6 +41,12 @@ internal enum AutoConfigureInfoField [AsciiHash("dragonfly_version")] DragonflyVersion, + [AsciiHash("memurai_version")] + MemuraiVersion, + + [AsciiHash("redict_version")] + RedictVersion, + [AsciiHash("server_mode")] ServerMode, } diff --git a/src/StackExchange.Redis/Enums/ProductVariant.cs b/src/StackExchange.Redis/Enums/ProductVariant.cs index be20b16530..af89e8c96f 100644 --- a/src/StackExchange.Redis/Enums/ProductVariant.cs +++ b/src/StackExchange.Redis/Enums/ProductVariant.cs @@ -29,5 +29,15 @@ public enum ProductVariant /// Dragonfly, + /// + /// Memurai + /// + Memurai, + + /// + /// Redict + /// + Redict, + // if you want to add another variant here, please open an issue with the details (variant name, INFO output, etc.) } diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt index ad375aa6f4..33b5fa7ba6 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt @@ -2323,6 +2323,8 @@ StackExchange.Redis.ProductVariant.Garnet = 2 -> StackExchange.Redis.ProductVari StackExchange.Redis.ProductVariant.Redis = 0 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Valkey = 1 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Dragonfly = 3 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Memurai = 4 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Redict = 5 -> StackExchange.Redis.ProductVariant static StackExchange.Redis.RedisChannel.SubKeyEvent(StackExchange.Redis.KeyNotificationType type, int? database = null) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeyEvent(System.ReadOnlySpan type, int? database) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeySpaceEvent(StackExchange.Redis.KeyNotificationType type, in StackExchange.Redis.RedisKey key, int? database = null) -> StackExchange.Redis.RedisChannel diff --git a/src/StackExchange.Redis/ResultProcessor.cs b/src/StackExchange.Redis/ResultProcessor.cs index 692c4fa724..84c93e97ad 100644 --- a/src/StackExchange.Redis/ResultProcessor.cs +++ b/src/StackExchange.Redis/ResultProcessor.cs @@ -999,6 +999,14 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes productVariant = ProductVariant.Dragonfly; productVersion = valSpan.ToString(); break; + case AutoConfigureInfoField.MemuraiVersion: + productVariant = ProductVariant.Memurai; + productVersion = valSpan.ToString(); + break; + case AutoConfigureInfoField.RedictVersion: + productVariant = ProductVariant.Redict; + productVersion = valSpan.ToString(); + break; } } if (roleSeen && Format.TryParseEndPoint(primaryHost!, primaryPort, out var sep)) From 70fd6746b0c16c24cea13269f879254d1cd86c21 Mon Sep 17 00:00:00 2001 From: Ivan Tikhonov Date: Wed, 2 Sep 2026 17:21:11 +0300 Subject: [PATCH 3/4] add KeyDB without Version --- src/StackExchange.Redis/AutoConfigureInfoField.cs | 3 +++ src/StackExchange.Redis/Enums/ProductVariant.cs | 5 +++++ src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt | 3 ++- src/StackExchange.Redis/ResultProcessor.cs | 6 ++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/StackExchange.Redis/AutoConfigureInfoField.cs b/src/StackExchange.Redis/AutoConfigureInfoField.cs index 5e0c579bfe..303d57225c 100644 --- a/src/StackExchange.Redis/AutoConfigureInfoField.cs +++ b/src/StackExchange.Redis/AutoConfigureInfoField.cs @@ -49,6 +49,9 @@ internal enum AutoConfigureInfoField [AsciiHash("server_mode")] ServerMode, + + [AsciiHash("executable")] + Executable, } /// diff --git a/src/StackExchange.Redis/Enums/ProductVariant.cs b/src/StackExchange.Redis/Enums/ProductVariant.cs index af89e8c96f..fd3a17086c 100644 --- a/src/StackExchange.Redis/Enums/ProductVariant.cs +++ b/src/StackExchange.Redis/Enums/ProductVariant.cs @@ -39,5 +39,10 @@ public enum ProductVariant /// Redict, + /// + /// KeyDB + /// + KeyDB, + // if you want to add another variant here, please open an issue with the details (variant name, INFO output, etc.) } diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt index 33b5fa7ba6..86944af4d9 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt @@ -2319,12 +2319,13 @@ StackExchange.Redis.LCSMatchResult.LCSPosition.Start.get -> long StackExchange.Redis.RedisType.VectorSet = 8 -> StackExchange.Redis.RedisType StackExchange.Redis.IServer.GetProductVariant(out string! version) -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant -StackExchange.Redis.ProductVariant.Garnet = 2 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Redis = 0 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Valkey = 1 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Garnet = 2 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Dragonfly = 3 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Memurai = 4 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Redict = 5 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.KeyDB = 6 -> StackExchange.Redis.ProductVariant static StackExchange.Redis.RedisChannel.SubKeyEvent(StackExchange.Redis.KeyNotificationType type, int? database = null) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeyEvent(System.ReadOnlySpan type, int? database) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeySpaceEvent(StackExchange.Redis.KeyNotificationType type, in StackExchange.Redis.RedisKey key, int? database = null) -> StackExchange.Redis.RedisChannel diff --git a/src/StackExchange.Redis/ResultProcessor.cs b/src/StackExchange.Redis/ResultProcessor.cs index 84c93e97ad..6db32e7a39 100644 --- a/src/StackExchange.Redis/ResultProcessor.cs +++ b/src/StackExchange.Redis/ResultProcessor.cs @@ -1007,6 +1007,12 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes productVariant = ProductVariant.Redict; productVersion = valSpan.ToString(); break; + case AutoConfigureInfoField.Executable: + if (valSpan.EndsWith("/keydb-server")) + { + productVariant = ProductVariant.KeyDB; + } + break; } } if (roleSeen && Format.TryParseEndPoint(primaryHost!, primaryPort, out var sep)) From 6bf854103b6bfa11bebdbcfd882c2d569b0aa80f Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Thu, 3 Sep 2026 09:14:56 +0100 Subject: [PATCH 4/4] Track the new ProductVariant members as unshipped, and simplify KeyDB detection New enum members belong in PublicAPI.Unshipped.txt, not directly in Shipped.txt (which should only reflect what's actually released). Also collapse the KeyDB executable check into a switch pattern guard. --- src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt | 6 +----- src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt | 4 ++++ src/StackExchange.Redis/ResultProcessor.cs | 7 ++----- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt index 86944af4d9..605f04040e 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt @@ -2319,13 +2319,9 @@ StackExchange.Redis.LCSMatchResult.LCSPosition.Start.get -> long StackExchange.Redis.RedisType.VectorSet = 8 -> StackExchange.Redis.RedisType StackExchange.Redis.IServer.GetProductVariant(out string! version) -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Garnet = 2 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Redis = 0 -> StackExchange.Redis.ProductVariant StackExchange.Redis.ProductVariant.Valkey = 1 -> StackExchange.Redis.ProductVariant -StackExchange.Redis.ProductVariant.Garnet = 2 -> StackExchange.Redis.ProductVariant -StackExchange.Redis.ProductVariant.Dragonfly = 3 -> StackExchange.Redis.ProductVariant -StackExchange.Redis.ProductVariant.Memurai = 4 -> StackExchange.Redis.ProductVariant -StackExchange.Redis.ProductVariant.Redict = 5 -> StackExchange.Redis.ProductVariant -StackExchange.Redis.ProductVariant.KeyDB = 6 -> StackExchange.Redis.ProductVariant static StackExchange.Redis.RedisChannel.SubKeyEvent(StackExchange.Redis.KeyNotificationType type, int? database = null) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeyEvent(System.ReadOnlySpan type, int? database) -> StackExchange.Redis.RedisChannel static StackExchange.Redis.RedisChannel.SubKeySpaceEvent(StackExchange.Redis.KeyNotificationType type, in StackExchange.Redis.RedisKey key, int? database = null) -> StackExchange.Redis.RedisChannel diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt index 419c74dc23..8022993e4b 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt @@ -111,3 +111,7 @@ static StackExchange.Redis.BitFieldOperation.IncrementBy(StackExchange.Redis.Bit static StackExchange.Redis.BitFieldOperation.operator ==(StackExchange.Redis.BitFieldOperation x, StackExchange.Redis.BitFieldOperation y) -> bool static StackExchange.Redis.BitFieldOperation.operator !=(StackExchange.Redis.BitFieldOperation x, StackExchange.Redis.BitFieldOperation y) -> bool static StackExchange.Redis.BitFieldOperation.Set(StackExchange.Redis.BitFieldEncoding encoding, StackExchange.Redis.BitFieldOffset offset, long value, StackExchange.Redis.BitFieldOverflow overflow = StackExchange.Redis.BitFieldOverflow.Wrap) -> StackExchange.Redis.BitFieldOperation +StackExchange.Redis.ProductVariant.Dragonfly = 3 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Memurai = 4 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.Redict = 5 -> StackExchange.Redis.ProductVariant +StackExchange.Redis.ProductVariant.KeyDB = 6 -> StackExchange.Redis.ProductVariant diff --git a/src/StackExchange.Redis/ResultProcessor.cs b/src/StackExchange.Redis/ResultProcessor.cs index 6db32e7a39..68662aa29f 100644 --- a/src/StackExchange.Redis/ResultProcessor.cs +++ b/src/StackExchange.Redis/ResultProcessor.cs @@ -1007,11 +1007,8 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes productVariant = ProductVariant.Redict; productVersion = valSpan.ToString(); break; - case AutoConfigureInfoField.Executable: - if (valSpan.EndsWith("/keydb-server")) - { - productVariant = ProductVariant.KeyDB; - } + case AutoConfigureInfoField.Executable when valSpan.EndsWith("/keydb-server"): + productVariant = ProductVariant.KeyDB; break; } }