diff --git a/docs/Configuration.md b/docs/Configuration.md index 9297386a8..b86f2148d 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -368,13 +368,8 @@ broken connection. This requires RESP3, and the client asks for it per connectio | `enabled` | **Required**: ask, and reject the connection unless notifications are live. Only point this at a deployment you know supports them. | Note that `enabled` means *required*, not merely *on* - it is the cross-client name for that mode, and it will -refuse a connection that cannot deliver notifications, including any RESP2 connection. - -**For now this is purely opt-in: you must set `maintNotifications` yourself.** The `amr`, `rediscloud` and -`enterprise` providers are intended to select `auto` for you, so that on those deployments nothing needs -setting - but that auto-enlistment is held back until the feature has been through formal acceptance testing, -and is expected in a follow-up release. Naming a provider today sets its other defaults without turning -notifications on. +refuse a connection that cannot deliver notifications, including any RESP2 connection. The `amr`, `rediscloud` +and `enterprise` providers select `auto` for you, so on those deployments you need not set anything. While a disruption has been announced, command timeouts are relaxed - raised to `maintRelaxedTimeout`, never lowered, so a caller with a more generous timeout keeps it. The window ends when the server says the disruption diff --git a/docs/ServerMaintenanceEvent.md b/docs/ServerMaintenanceEvent.md index 91790bf46..3a6ebf380 100644 --- a/docs/ServerMaintenanceEvent.md +++ b/docs/ServerMaintenanceEvent.md @@ -29,34 +29,29 @@ Server-side you may also see it discussed as *maintenance mode*, *shard migratio ## Do I need to configure anything? -**Yes — for now.** In this release maintenance notifications are **purely opt-in**: nothing turns them on for you, whatever you connect to. You get them only by asking, with `maintNotifications=Auto` (or `Enabled`). +Usually not. If you connect using the hostname your provider gave you, the matching options provider recognizes it and turns the feature on for you. -> **This is temporary.** The intent is that the options providers enlist you automatically, so that connecting to a recognized Redis Cloud or Azure Managed Redis hostname turns the feature on without any configuration — exactly as the table below describes. That is held back only until the feature has been through formal acceptance testing, and is expected to land in a follow-up release. Until then, treat the "will be" column as a statement of direction, not of current behaviour. - -| You connect to | Recognized as | Notifications now | Will be | -|---|---|---|---| -| `something.cloud.redislabs.com`, `.cloud.redis.io`, `.redislabs.com` | Redis Cloud | **off** unless asked | on (`Auto`) | -| `something.redis.azure.net`, `.redisenterprise.cache.azure.net` | Azure Managed Redis | **off** unless asked | on (`Auto`) | -| `defaults=enterprise`, `defaults=rediscloud`, `defaults=amr` | named explicitly | **off** unless asked | on (`Auto`) | -| your own hostname, a CNAME, private DNS, or through a proxy | nothing | **off** | **off** | -| a self-managed Redis Enterprise cluster | nothing (there is no DNS pattern to recognize) | **off** | **off** | +| You connect to | Recognized as | Notifications | +|---|---|---| +| `something.cloud.redislabs.com`, `.cloud.redis.io`, `.redislabs.com` | Redis Cloud | on (`Auto`) | +| `something.redis.azure.net`, `.redisenterprise.cache.azure.net` | Azure Managed Redis | on (`Auto`) | +| `defaults=enterprise`, `defaults=rediscloud`, `defaults=amr` | named explicitly | on (`Auto`) | +| your own hostname, a CNAME, private DNS, or through a proxy | nothing | **off** | +| a self-managed Redis Enterprise cluster | nothing (there is no DNS pattern to recognize) | **off** | -Nothing fails when the feature is off: the connection works normally and you simply never receive a notification. So to use it today, ask for it explicitly. Either: +The last two rows are the ones to know about, because nothing fails: the connection works normally and you simply never receive a notification. If your endpoint does not look like your provider's, say so explicitly. Either: ```csharp -// change nothing except this feature -var options = ConfigurationOptions.Parse("my-redis.internal.example.com:6379,maintNotifications=Auto"); +// the whole deployment posture: prefer RESP3, skip the OSS config-broadcast channel, and ask for notifications +var options = ConfigurationOptions.Parse("my-redis.internal.example.com:6379,defaults=enterprise"); ``` -or, to take the whole deployment posture as well - prefer RESP3 and skip the OSS config-broadcast channel: +or, to change nothing except this feature: ```csharp -var options = ConfigurationOptions.Parse( - "my-redis.internal.example.com:6379,defaults=enterprise,maintNotifications=Auto"); +var options = ConfigurationOptions.Parse("my-redis.internal.example.com:6379,maintNotifications=Auto"); ``` -Note that `maintNotifications` is needed in *both* forms for now: while the feature is opt-in, naming a provider sets that provider's other defaults but does not turn notifications on. Once auto-enlistment lands, `defaults=enterprise` alone will be enough. - `defaults=` accepts `rediscloud`, `enterprise`, `amr` and `azure`; see [Configuration](Configuration.md) for what each provider sets. It is also the right answer for a *hosted* deployment reached somewhere its own provider cannot see it, such as behind a CNAME or a private endpoint. ### RESP3 is required, and is already the default diff --git a/docs/exp/SER010.md b/docs/exp/SER010.md index 89dcbff70..a09ccd279 100644 --- a/docs/exp/SER010.md +++ b/docs/exp/SER010.md @@ -17,12 +17,6 @@ The feature is experimental here for three separate reasons: timeout relaxation, then endpoint handoff. Behaviour may therefore change materially between versions while the diagnostic is in place, even where the API does not. -**Currently purely opt-in.** Nothing enables this for you: the options providers for Redis Cloud, Azure -Managed Redis and Redis Enterprise are intended to select `Auto` so that a recognized endpoint needs no -configuration, but that auto-enlistment is held back until the feature has been through formal acceptance -testing, and is expected in a follow-up release. Until then the only thing that turns notifications on is -setting `maintNotifications` yourself. - `MaintenanceNotificationMode`: - `Disabled` (the default) - never ask; the server sends nothing. diff --git a/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs b/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs index 1f3198eda..51e2caacf 100644 --- a/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs +++ b/src/StackExchange.Redis/Configuration/AzureManagedRedisOptionsProvider.cs @@ -71,16 +71,17 @@ public override Task AfterConnectAsync(ConnectionMultiplexer muxer, Action public override string ConfigurationChannel => ""; // disable on AMR - // Auto-enlistment, deliberately withheld for now; maintenance notifications ship purely opt-in, and - // this goes back in a follow-up once the feature has been through formal acceptance testing. Kept here - // commented rather than deleted so that what returns is exactly what was reviewed. - // - // Pre-emptive: AMR does not emit these yet, and support is being added concurrently with this - // client-side work. Auto is what makes that safe - until the server side ships, the opt-in is refused - // and the feature stays off, and it then starts working without anybody needing to change a connection - // string. AMR also already prefers RESP3 here, which the feature requires. - // - // [Experimental(Experiments.MaintenanceNotifications, UrlFormat = Experiments.UrlFormat)] - // public override MaintenanceNotificationMode MaintenanceNotifications => MaintenanceNotificationMode.Auto; + /// + /// Ask for maintenance notifications, tolerating a server that doesn't offer them. + /// + /// + /// Pre-emptive: AMR does not emit these yet, and support is being added concurrently with this + /// client-side work. is what makes that safe - until + /// the server side ships, the opt-in is refused and the feature stays off, and it then starts working + /// without anybody needing to change a connection string. AMR also already prefers RESP3 here, which + /// the feature requires. + /// + [Experimental(Experiments.MaintenanceNotifications, UrlFormat = Experiments.UrlFormat)] + public override MaintenanceNotificationMode MaintenanceNotifications => MaintenanceNotificationMode.Auto; } } diff --git a/src/StackExchange.Redis/Configuration/RedisCloudOptionsProvider.cs b/src/StackExchange.Redis/Configuration/RedisCloudOptionsProvider.cs index 8787a578a..fc00c4f9b 100644 --- a/src/StackExchange.Redis/Configuration/RedisCloudOptionsProvider.cs +++ b/src/StackExchange.Redis/Configuration/RedisCloudOptionsProvider.cs @@ -59,16 +59,17 @@ private static bool IsHostInDomains(string hostName, string[] domains) /// public override string ConfigurationChannel => ""; - // Auto-enlistment, deliberately withheld for now; maintenance notifications ship purely opt-in, and - // this goes back in a follow-up once the feature has been through formal acceptance testing. Kept here - // commented rather than deleted so that what returns is exactly what was reviewed. - // - // This is the deployment family the feature exists for, and Auto rather than Enabled because a - // database that has not been updated yet must keep working: the opt-in is then refused and the feature - // stays off, rather than the connection being rejected. - // - // [Experimental(Experiments.MaintenanceNotifications, UrlFormat = Experiments.UrlFormat)] - // public override MaintenanceNotificationMode MaintenanceNotifications => MaintenanceNotificationMode.Auto; + /// + /// Ask for maintenance notifications, tolerating a server that doesn't offer them. + /// + /// + /// This is the deployment family the feature exists for. + /// rather than because a database that has not been + /// updated yet must keep working: the opt-in is then refused and the feature stays off, rather than the + /// connection being rejected. + /// + [Experimental(Experiments.MaintenanceNotifications, UrlFormat = Experiments.UrlFormat)] + public override MaintenanceNotificationMode MaintenanceNotifications => MaintenanceNotificationMode.Auto; // Two things AzureManagedRedisOptionsProvider does that are deliberately *not* repeated here: // diff --git a/src/StackExchange.Redis/Configuration/RedisEnterpriseOptionsProvider.cs b/src/StackExchange.Redis/Configuration/RedisEnterpriseOptionsProvider.cs index aafe4c54d..87634fbf5 100644 --- a/src/StackExchange.Redis/Configuration/RedisEnterpriseOptionsProvider.cs +++ b/src/StackExchange.Redis/Configuration/RedisEnterpriseOptionsProvider.cs @@ -31,20 +31,17 @@ public class RedisEnterpriseOptionsProvider : DefaultOptionsProvider /// public override string ConfigurationChannel => ""; - // Auto-enlistment, deliberately withheld for now; maintenance notifications ship purely opt-in, and - // this goes back in a follow-up once the feature has been through formal acceptance testing. Kept here - // commented rather than deleted so that what returns is exactly what was reviewed. - // - // Note this provider is reached only by naming it (defaults=enterprise), never by endpoint matching, - // so restoring it enlists nobody who did not already ask for this deployment posture. It is withheld - // anyway, so that in this release the *only* thing that turns the feature on is maintNotifications. - // - // Auto rather than Enabled: a cluster that has not been updated yet, or has the feature switched off, - // must keep working. Choose Enabled explicitly if you would rather a connection be refused than run - // without advance warning. - // - // [Experimental(Experiments.MaintenanceNotifications, UrlFormat = Experiments.UrlFormat)] - // public override MaintenanceNotificationMode MaintenanceNotifications => MaintenanceNotificationMode.Auto; + /// + /// Ask for maintenance notifications, tolerating a server that doesn't offer them. + /// + /// + /// rather than + /// : a cluster that has not been updated yet, or has + /// the feature switched off, must keep working. Choose Enabled explicitly if you would rather a + /// connection be refused than run without advance warning. + /// + [Experimental(Experiments.MaintenanceNotifications, UrlFormat = Experiments.UrlFormat)] + public override MaintenanceNotificationMode MaintenanceNotifications => MaintenanceNotificationMode.Auto; // Note: no GetDefaultSsl and no DefaultVersion override. Both are deployment choices here rather than // properties of the product - TLS is configured per database, and the version is whatever was diff --git a/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt b/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt index ab058de62..43eab028e 100644 --- a/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,4 @@ #nullable enable +[SER010]override StackExchange.Redis.Configuration.AzureManagedRedisOptionsProvider.MaintenanceNotifications.get -> StackExchange.Redis.MaintenanceNotificationMode +[SER010]override StackExchange.Redis.Configuration.RedisCloudOptionsProvider.MaintenanceNotifications.get -> StackExchange.Redis.MaintenanceNotificationMode +[SER010]override StackExchange.Redis.Configuration.RedisEnterpriseOptionsProvider.MaintenanceNotifications.get -> StackExchange.Redis.MaintenanceNotificationMode diff --git a/tests/StackExchange.Redis.Tests/DefaultOptionsTests.cs b/tests/StackExchange.Redis.Tests/DefaultOptionsTests.cs index 445027bd4..1f508f262 100644 --- a/tests/StackExchange.Redis.Tests/DefaultOptionsTests.cs +++ b/tests/StackExchange.Redis.Tests/DefaultOptionsTests.cs @@ -197,17 +197,17 @@ public void RedisCloudDoesNotInheritTheAzureManagedAssumptions() } [Theory] - [InlineData("contoso.redis.azure.net", MaintenanceNotificationMode.Disabled)] // AMR: will be Auto - [InlineData("contoso.cloud.redislabs.com", MaintenanceNotificationMode.Disabled)] // Redis Cloud: will be Auto + [InlineData("contoso.redis.azure.net", MaintenanceNotificationMode.Auto)] // AMR + [InlineData("contoso.cloud.redislabs.com", MaintenanceNotificationMode.Auto)] // Redis Cloud [InlineData("contoso.redis.cache.windows.net", MaintenanceNotificationMode.Disabled)] // classic Azure: stays off [InlineData("contoso.example.com", MaintenanceNotificationMode.Disabled)] // and so does anything unrecognized public void MaintenanceNotificationDefaultPerProvider(string hostName, MaintenanceNotificationMode expected) { - // Every endpoint is Disabled for now: maintenance notifications ship purely opt-in, so *nothing* - // enlists you and the only thing that turns them on is setting maintNotifications yourself. The - // providers for AMR and Redis Cloud are intended to select Auto - see the commented-out overrides on - // each - and this theory is what flips back when auto-enlistment lands: the first two rows become - // Auto, and the last two stay Disabled because nothing recognizes them either way. + // The recognized hosted families enlist automatically, which is the whole point of the providers: a + // connection string that names nothing but the hostname gets the feature. Auto rather than Enabled so + // that a deployment which cannot deliver keeps working - the opt-in is refused and the feature stays + // off. The last two rows stay Disabled because nothing recognizes them either way, and they are what + // stops this test passing merely because everything returns the same answer. var epc = new EndPointCollection(new List() { new DnsEndPoint(hostName, 0) }); var provider = DefaultOptionsProvider.GetProvider(epc); Output.WriteLine($"{hostName} -> {provider.GetType().Name}");