From 7c9faf8e01cde095cd8a4b7ad2c7fc639dcdfffc Mon Sep 17 00:00:00 2001 From: Nick Craver Date: Tue, 9 Dec 2025 11:37:53 -0500 Subject: [PATCH] Options: Split out AMR to its own options provider This breaks out AMR into its own default options provider to specify default versions but also allow us to do things like specify default RESP later on. --- .../AzureManagedRedisOptionsProvider.cs | 61 +++++++++++++++++++ .../Configuration/AzureOptionsProvider.cs | 18 +----- .../PublicAPI/PublicAPI.Shipped.txt | 7 +++ src/StackExchange.Redis/RedisFeatures.cs | 1 + 4 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs diff --git a/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs b/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs new file mode 100644 index 000000000..863d9533d --- /dev/null +++ b/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs @@ -0,0 +1,61 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using StackExchange.Redis.Maintenance; + +namespace StackExchange.Redis.Configuration +{ + /// + /// Options provider for Azure Managed Redis environments. + /// + public class AzureManagedRedisOptionsProvider : DefaultOptionsProvider + { + /// + /// Allow connecting after startup, in the cases where remote cache isn't ready or is overloaded. + /// + public override bool AbortOnConnectFail => false; + + /// + /// The minimum version of Redis in Azure Managed Redis is 7.4, so use the widest set of available commands when connecting. + /// + public override Version DefaultVersion => RedisFeatures.v7_4_0; + + private static readonly string[] azureManagedRedisDomains = + [ + ".redis.azure.net", + ".redis.chinacloudapi.cn", + ".redis.usgovcloudapi.net", + ]; + + /// + public override bool IsMatch(EndPoint endpoint) + { + if (endpoint is DnsEndPoint dnsEp && IsHostInDomains(dnsEp.Host, azureManagedRedisDomains)) + { + return true; + } + + return false; + } + + private bool IsHostInDomains(string hostName, string[] domains) + { + foreach (var domain in domains) + { + if (hostName.EndsWith(domain, StringComparison.InvariantCultureIgnoreCase)) + { + return true; + } + } + + return false; + } + + /// + public override Task AfterConnectAsync(ConnectionMultiplexer muxer, Action log) + => AzureMaintenanceEvent.AddListenerAsync(muxer, log); + + /// + public override bool GetDefaultSsl(EndPointCollection endPoints) => true; + } +} diff --git a/src/StackExchange.Redis/Configuration/AzureOptionsProvider.cs b/src/StackExchange.Redis/Configuration/AzureOptionsProvider.cs index fb01f0704..625ac899b 100644 --- a/src/StackExchange.Redis/Configuration/AzureOptionsProvider.cs +++ b/src/StackExchange.Redis/Configuration/AzureOptionsProvider.cs @@ -32,22 +32,12 @@ public class AzureOptionsProvider : DefaultOptionsProvider ".redisenterprise.cache.azure.net", }; - private static readonly string[] azureManagedRedisDomains = new[] - { - ".redis.azure.net", - ".redis.chinacloudapi.cn", - ".redis.usgovcloudapi.net", - }; - /// public override bool IsMatch(EndPoint endpoint) { - if (endpoint is DnsEndPoint dnsEp) + if (endpoint is DnsEndPoint dnsEp && IsHostInDomains(dnsEp.Host, azureRedisDomains)) { - if (IsHostInDomains(dnsEp.Host, azureRedisDomains) || IsHostInDomains(dnsEp.Host, azureManagedRedisDomains)) - { - return true; - } + return true; } return false; @@ -82,10 +72,6 @@ public override bool GetDefaultSsl(EndPointCollection endPoints) { return true; } - if (dns.Port == 10000 && IsHostInDomains(dns.Host, azureManagedRedisDomains)) - { - return true; // SSL is enabled by default on AMR caches - } break; case IPEndPoint ip: if (ip.Port == 6380) diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt index 5eaa42b3f..905ce56d7 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt @@ -14,6 +14,11 @@ override StackExchange.Redis.Configuration.AzureOptionsProvider.AfterConnectAsyn override StackExchange.Redis.Configuration.AzureOptionsProvider.DefaultVersion.get -> System.Version! override StackExchange.Redis.Configuration.AzureOptionsProvider.GetDefaultSsl(StackExchange.Redis.EndPointCollection! endPoints) -> bool override StackExchange.Redis.Configuration.AzureOptionsProvider.IsMatch(System.Net.EndPoint! endpoint) -> bool +override StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.AbortOnConnectFail.get -> bool +override StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.AfterConnectAsync(StackExchange.Redis.ConnectionMultiplexer! muxer, System.Action! log) -> System.Threading.Tasks.Task! +override StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.DefaultVersion.get -> System.Version! +override StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.GetDefaultSsl(StackExchange.Redis.EndPointCollection! endPoints) -> bool +override StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.IsMatch(System.Net.EndPoint! endpoint) -> bool override StackExchange.Redis.ConfigurationOptions.ToString() -> string! override StackExchange.Redis.ConnectionCounters.ToString() -> string! override StackExchange.Redis.ConnectionFailedEventArgs.ToString() -> string! @@ -199,6 +204,8 @@ StackExchange.Redis.ConditionResult StackExchange.Redis.ConditionResult.WasSatisfied.get -> bool StackExchange.Redis.Configuration.AzureOptionsProvider StackExchange.Redis.Configuration.AzureOptionsProvider.AzureOptionsProvider() -> void +StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider +StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.AzureManagedRedisOptionsProvider() -> void StackExchange.Redis.Configuration.DefaultOptionsProvider StackExchange.Redis.Configuration.DefaultOptionsProvider.ClientName.get -> string! StackExchange.Redis.Configuration.DefaultOptionsProvider.DefaultOptionsProvider() -> void diff --git a/src/StackExchange.Redis/RedisFeatures.cs b/src/StackExchange.Redis/RedisFeatures.cs index 0e6b410a9..d097e418c 100644 --- a/src/StackExchange.Redis/RedisFeatures.cs +++ b/src/StackExchange.Redis/RedisFeatures.cs @@ -45,6 +45,7 @@ namespace StackExchange.Redis v7_2_0_rc1 = new Version(7, 1, 240), // 7.2 RC1 is version 7.1.240 v7_4_0_rc1 = new Version(7, 3, 240), // 7.4 RC1 is version 7.3.240 v7_4_0_rc2 = new Version(7, 3, 241), // 7.4 RC2 is version 7.3.241 + v7_4_0 = new Version(7, 4, 0), v8_0_0_M04 = new Version(7, 9, 227), // 8.0 M04 is version 7.9.227 v8_2_0_rc1 = new Version(8, 1, 240), // 8.2 RC1 is version 8.1.240 v8_4_0_rc1 = new Version(8, 3, 224); // 8.4 RC1 is version 8.3.224