Repository: FoundatioFx/Foundatio.Redis
Pull request #101: Add redis database selection
Author: login: TeddyAlbina
Created: 2025-05-14T15:15:32Z | Merged: 2025-05-19T06:02:46Z

Actually is it not possible to setup the redis database to use. This evolution aims to add this possibility.


Diff:
diff --git a/src/Foundatio.Redis/Cache/RedisCacheClient.cs b/src/Foundatio.Redis/Cache/RedisCacheClient.cs
index 6f4f704..7cf871c 100644
--- a/src/Foundatio.Redis/Cache/RedisCacheClient.cs
+++ b/src/Foundatio.Redis/Cache/RedisCacheClient.cs
@@ -35,15 +35,17 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
         options.ConnectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
     }
 
     public RedisCacheClient(Builder<RedisCacheClientOptionsBuilder, RedisCacheClientOptions> config)
         : this(config(new RedisCacheClientOptionsBuilder()).Build())
     {
+
     }
 
-    public IDatabase Database => _options.ConnectionMultiplexer.GetDatabase();
+    public IDatabase Database => _options.ConnectionMultiplexer.GetDatabase(_options.Database);
 
     public Task<bool> RemoveAsync(string key)
     {
@@ -84,8 +86,8 @@ public async Task<int> RemoveAllAsync(IEnumerable<string> keys = null)
 
                 try
                 {
-                    long dbSize = await server.DatabaseSizeAsync().AnyContext();
-                    await server.FlushDatabaseAsync().AnyContext();
+                    long dbSize = await server.DatabaseSizeAsync(_options.Database).AnyContext();
+                    await server.FlushDatabaseAsync(_options.Database).AnyContext();
                     deleted += dbSize;
                     continue;
                 }
@@ -100,7 +102,7 @@ public async Task<int> RemoveAllAsync(IEnumerable<string> keys = null)
                     // A Performance win could be had if we are sure dbSize didn't fail and we know nothing was changing
                     // keys while we were deleting.
                     var seen = new HashSet<RedisKey>();
-                    await foreach (var key in server.KeysAsync().ConfigureAwait(false))
+                    await foreach (var key in server.KeysAsync(_options.Database).ConfigureAwait(false))
                         seen.Add(key);
 
                     foreach (var batch in seen.Batch(batchSize))
diff --git a/src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs b/src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
index 9a80b69..e9df913 100644
--- a/src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
+++ b/src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
@@ -1,4 +1,5 @@
-﻿using StackExchange.Redis;
+﻿using System;
+using StackExchange.Redis;
 
 namespace Foundatio.Caching;
 
@@ -16,6 +17,10 @@ public class RedisCacheClientOptions : SharedOptions
     /// </summary>
     public CommandFlags ReadMode { get; set; } = CommandFlags.None;
 
+    /// <summary>
+    /// The database to use
+    /// </summary>
+    public int Database { get; set; } = -1;
 }
 
 public class RedisCacheClientOptionsBuilder : SharedOptionsBuilder<RedisCacheClientOptions, RedisCacheClientOptionsBuilder>
@@ -37,4 +42,15 @@ public RedisCacheClientOptionsBuilder ReadMode(CommandFlags commandFlags)
         Target.ReadMode = commandFlags;
         return this;
     }
+
+    public RedisCacheClientOptionsBuilder UseDatabase(int database)
+    {
+        if (database < -1)  // We consider -1 as a valid value in respect for the default behaviour of stack exchange redis
+        {
+            throw new ArgumentOutOfRangeException(nameof(database), "database number cannot be less than -1.");
+        }
+
+        Target.Database = database;
+        return this;
+    }
 }
diff --git a/src/Foundatio.Redis/Cache/RedisHybridCacheClient.cs b/src/Foundatio.Redis/Cache/RedisHybridCacheClient.cs
index bd10cc8..75cb056 100644
--- a/src/Foundatio.Redis/Cache/RedisHybridCacheClient.cs
+++ b/src/Foundatio.Redis/Cache/RedisHybridCacheClient.cs
@@ -9,7 +9,8 @@ public RedisHybridCacheClient(RedisHybridCacheClientOptions options, InMemoryCac
                 .Serializer(options.Serializer)
                 .LoggerFactory(options.LoggerFactory)
                 .ShouldThrowOnSerializationError(options.ShouldThrowOnSerializationError)
-                .ReadMode(options.ReadMode)),
+                .ReadMode(options.ReadMode)
+                .UseDatabase(options.Database)),
             new RedisMessageBus(o => o
                 .Subscriber(options.ConnectionMultiplexer.GetSubscriber())
                 .Topic(options.RedisChannelName)
diff --git a/src/Foundatio.Redis/Cache/RedisHybridCacheClientOptions.cs b/src/Foundatio.Redis/Cache/RedisHybridCacheClientOptions.cs
index 3e39423..a201ee3 100644
--- a/src/Foundatio.Redis/Cache/RedisHybridCacheClientOptions.cs
+++ b/src/Foundatio.Redis/Cache/RedisHybridCacheClientOptions.cs
@@ -1,4 +1,5 @@
-﻿using StackExchange.Redis;
+﻿using System;
+using StackExchange.Redis;
 
 namespace Foundatio.Caching;
 
@@ -28,4 +29,15 @@ public RedisHybridCacheClientOptionsBuilder ShouldThrowOnSerializationError(bool
         Target.ShouldThrowOnSerializationError = shouldThrow;
         return this;
     }
+
+    public RedisHybridCacheClientOptionsBuilder UseDatabase(int database)
+    {
+        if (database < -1)  // We consider -1 as a valid value in respect for the default behaviour of stack exchange redis
+        {
+            throw new ArgumentOutOfRangeException(nameof(database), "database number cannot be less than 0.");
+        }
+
+        Target.Database = database;
+        return this;
+    }
 }
diff --git a/src/Foundatio.Redis/Queues/RedisQueue.cs b/src/Foundatio.Redis/Queues/RedisQueue.cs
index 7102197..6b1477f 100644
--- a/src/Foundatio.Redis/Queues/RedisQueue.cs
+++ b/src/Foundatio.Redis/Queues/RedisQueue.cs
@@ -44,6 +44,7 @@ public RedisQueue(RedisQueueOptions<T> options) : base(options)
             throw new ArgumentException("ConnectionMultiplexer is required.");
 
         options.ConnectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
+
         _cache = new RedisCacheClient(new RedisCacheClientOptions { ConnectionMultiplexer = options.ConnectionMultiplexer, Serializer = _serializer });
 
         _payloadTimeToLive = GetPayloadTtl();
@@ -65,7 +66,7 @@ public RedisQueue(RedisQueueOptions<T> options) : base(options)
     public RedisQueue(Builder<RedisQueueOptionsBuilder<T>, RedisQueueOptions<T>> config)
         : this(config(new RedisQueueOptionsBuilder<T>()).Build()) { }
 
-    public IDatabase Database => _options.ConnectionMultiplexer.GetDatabase();
+    public IDatabase Database => _options.ConnectionMultiplexer.GetDatabase(_options.Database);
 
     protected override Task EnsureQueueCreatedAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
 
diff --git a/src/Foundatio.Redis/Queues/RedisQueueOptions.cs b/src/Foundatio.Redis/Queues/RedisQueueOptions.cs
index 1dd95c5..f55ea41 100644
--- a/src/Foundatio.Redis/Queues/RedisQueueOptions.cs
+++ b/src/Foundatio.Redis/Queues/RedisQueueOptions.cs
@@ -12,6 +12,7 @@ public class RedisQueueOptions<T> : SharedQueueOptions<T> where T : class
     public TimeSpan DeadLetterTimeToLive { get; set; } = TimeSpan.FromDays(1);
     public int DeadLetterMaxItems { get; set; } = 100;
     public bool RunMaintenanceTasks { get; set; } = true;
+    public int Database { get; set; } = -1;
 }
 
 public class RedisQueueOptionsBuilder<T> : SharedQueueOptionsBuilder<T, RedisQueueOptions<T>, RedisQueueOptionsBuilder<T>> where T : class
@@ -51,4 +52,15 @@ public RedisQueueOptionsBuilder<T> RunMaintenanceTasks(bool runMaintenanceTasks)
         Target.RunMaintenanceTasks = runMaintenanceTasks;
         return this;
     }
+
+    public RedisQueueOptionsBuilder<T> UseDatabase(int database)
+    {
+        if (database < -1) // We consider -1 as a valid value in respect for the default behaviour of stack exchange redis
+        {
+            throw new ArgumentOutOfRangeException(nameof(database), "database number cannot be less than 0.");
+        }
+
+        Target.Database = database;
+        return this;
+    }
 }


Reviews:
user: login: niemyjski
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T02:06:19Z
user: login: niemyjski
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T02:09:03Z
user: login: niemyjski
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T02:09:39Z
user: login: niemyjski
body: Thanks a ton for this PR! I left a few comments and would love your thoughts around db constraints.
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T02:10:38Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR adds the ability to select a specific Redis database for queues and cache clients. Key changes include:
- Introducing a new nullable DbId property to options classes.
- Adding builder methods (UseDatabase) to set the database index.
- Updating database accessor logic in queue and cache client classes to pass the selected database index.

### Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

<details>
<summary>Show a summary per file</summary>

| File                                                          | Description                                                              |
| ------------------------------------------------------------- | ------------------------------------------------------------------------ |
| src/Foundatio.Redis/Queues/RedisQueueOptions.cs               | Added DbId property and UseDatabase builder method for queue options.    |
| src/Foundatio.Redis/Queues/RedisQueue.cs                       | Updated constructor and Database property to use the provided DbId.      |
| src/Foundatio.Redis/Cache/RedisHybridCacheClientOptions.cs     | Added UseDatabase builder method in cache client options.                |
| src/Foundatio.Redis/Cache/RedisHybridCacheClient.cs            | Integrated the DbId update in the client configuration chain.            |
| src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs           | Added DbId property and UseDatabase builder method in cache options.       |
| src/Foundatio.Redis/Cache/RedisCacheClient.cs                  | Updated DbId assignment, Database property, and related calls to use DbId. |
</details>





state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T02:11:31Z
user: login: ejsmith
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T02:18:45Z
user: login: niemyjski
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T02:21:58Z
user: login: ejsmith
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T02:24:00Z
user: login: ejsmith
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T02:26:09Z
user: login: TeddyAlbina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T06:02:21Z
user: login: TeddyAlbina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T06:08:43Z
user: login: TeddyAlbina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T06:09:22Z
user: login: TeddyAlbina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T06:41:38Z
user: login: TeddyAlbina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T07:55:52Z
user: login: ejsmith
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T16:39:53Z
user: login: TeddyAlbina
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T03:04:06Z
user: login: ejsmith
body: Nice work. Thanks!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T03:05:27Z

Review comments:
diff_hunk: @@ -35,15 +36,19 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
+        _dbId = _options.DbId ?? -1;
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: niemyjski
body: since we already store _options I'm not sure if we need this.
created_at: 2025-05-15T02:06:19Z
author_association: MEMBER
diff_hunk: @@ -16,6 +16,7 @@ public class RedisCacheClientOptions : SharedOptions
     /// </summary>
     public CommandFlags ReadMode { get; set; } = CommandFlags.None;
 
+    public int? DbId { get; set; }
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: niemyjski
body: I know the stack exchange client takes an int, I think we should keep this non nullable and default to 0. Part of my wonders if We should almost convert to a byte because stand alone kind of defaults to max of 16 dbs but on some systems there is no limit...

The one edge case to all of this is we don't have any configuration to detect cluster mode and in cluster mode the database has to be set to 0.

With all of this said I think we should just do

```suggestion
    public int? Database { get; set; };
```
created_at: 2025-05-15T02:09:03Z
author_association: MEMBER
diff_hunk: @@ -37,4 +38,10 @@ public RedisCacheClientOptionsBuilder ReadMode(CommandFlags commandFlags)
         Target.ReadMode = commandFlags;
         return this;
     }
+
+    public RedisCacheClientOptionsBuilder UseDatabase(int? db)
+    {
+        Target.DbId = db;
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: niemyjski
body: I think we might want to add some validation here on the min value. I feel like if you are calling this maybe it should be >= 0?
created_at: 2025-05-15T02:09:39Z
author_association: MEMBER
diff_hunk: @@ -59,13 +60,15 @@ public RedisQueue(RedisQueueOptions<T> options) : base(options)
         var interval = _options.WorkItemTimeout > TimeSpan.FromSeconds(1) ? _options.WorkItemTimeout.Min(TimeSpan.FromMinutes(1)) : TimeSpan.FromSeconds(1);
         _maintenanceLockProvider = new ThrottlingLockProvider(_cache, 1, interval);
 
+        _dbId = options.DbId ?? -1;
path: src/Foundatio.Redis/Queues/RedisQueue.cs
user: login: Copilot
body: Using -1 as a default Redis database index may lead to unintended behavior if the underlying API expects the default database to be 0. Consider defaulting to 0 when options.DbId is null.
```suggestion
        _dbId = options.DbId ?? 0;
```
created_at: 2025-05-15T02:11:30Z
author_association: NONE
diff_hunk: @@ -35,15 +36,19 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
+        _dbId = _options.DbId ?? -1;
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: Copilot
body: Using -1 as a fallback for the Redis database index might cause issues, as the standard default is typically 0. It is recommended to default to 0 if no database id is specified.
```suggestion
        _dbId = _options.DbId ?? 0;
```
created_at: 2025-05-15T02:11:30Z
author_association: NONE
diff_hunk: @@ -16,6 +16,7 @@ public class RedisCacheClientOptions : SharedOptions
     /// </summary>
     public CommandFlags ReadMode { get; set; } = CommandFlags.None;
 
+    public int? DbId { get; set; }
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: ejsmith
body: Thanks @TeddyAlbina!

I don't agree with making this non-nullable. I want to know if the intent was to use a specific Db or not.

I think the name of this should be `Database` not `DbId`.
created_at: 2025-05-15T02:18:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -35,15 +36,19 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
+        _dbId = _options.DbId ?? -1;
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: niemyjski
body: ^^ I tend to agree with this, Looks like they went with -1 just to try to resolve it. We could just get this from `_options.Database` 

```cs
        public IDatabase GetDatabase(int db = -1, object? asyncState = null)
        {
            db = ApplyDefaultDatabase(db);
            
            
            
            ...
            
            
            
                    internal int ApplyDefaultDatabase(int db)
        {
            if (db == -1)
            {
                db = RawConfig.DefaultDatabase.GetValueOrDefault();
            }
            else if (db < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(db));
            }

            if (db != 0 && !RawConfig.Proxy.SupportsDatabases())
            {
                throw new NotSupportedException($"{RawConfig.Proxy} only supports database 0");
            }

            return db;
        }
        ```
created_at: 2025-05-15T02:21:58Z
author_association: MEMBER
diff_hunk: @@ -35,15 +36,19 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
+        _dbId = _options.DbId ?? -1;
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: ejsmith
body: I think we need to use a nullable int (same as the Redis library) and not default it at all. Let the Redis library decide what the default behavior is.
created_at: 2025-05-15T02:24:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -35,15 +36,19 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
+        _dbId = _options.DbId ?? -1;
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: ejsmith
body: Hmm... nevermind. The Redis library uses optional parameters not nullable int. It may be worth branching the code to either pass a database or not pass one to let Redis do whatever it thinks is best. They currently default to 0, but who is to say they can't change that in the future when you don't mean to specify a database.
created_at: 2025-05-15T02:26:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -35,15 +36,19 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
+        _dbId = _options.DbId ?? -1;
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: TeddyAlbina
body: I made it this way to not check each time if DbId is null or not. Also do you know the max value for db identifiers in Redis, ? I found confusing numbers on the web so i let the range of values open.
created_at: 2025-05-15T06:02:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,6 +16,7 @@ public class RedisCacheClientOptions : SharedOptions
     /// </summary>
     public CommandFlags ReadMode { get; set; } = CommandFlags.None;
 
+    public int? DbId { get; set; }
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: TeddyAlbina
body: For cluster mode detection i can add an INFO command to detect it. So if Database is not null and not equals 0 we first send the INFO command, if we are in cluster mode we throw an error indicating configuration doesn't make sens.
created_at: 2025-05-15T06:08:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -37,4 +38,10 @@ public RedisCacheClientOptionsBuilder ReadMode(CommandFlags commandFlags)
         Target.ReadMode = commandFlags;
         return this;
     }
+
+    public RedisCacheClientOptionsBuilder UseDatabase(int? db)
+    {
+        Target.DbId = db;
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: TeddyAlbina
body: Good idea.
created_at: 2025-05-15T06:09:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -37,4 +38,10 @@ public RedisCacheClientOptionsBuilder ReadMode(CommandFlags commandFlags)
         Target.ReadMode = commandFlags;
         return this;
     }
+
+    public RedisCacheClientOptionsBuilder UseDatabase(int? db)
+    {
+        Target.DbId = db;
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: TeddyAlbina
body: Because -1 is a valid value, i changed the Database property to non-nullable but with -1 as a default value and add a check so if a vaue inferior to -1 is passed as argument for UseDatabase i thow an out of range exception.
created_at: 2025-05-15T06:41:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,6 +16,7 @@ public class RedisCacheClientOptions : SharedOptions
     /// </summary>
     public CommandFlags ReadMode { get; set; } = CommandFlags.None;
 
+    public int? DbId { get; set; }
path: src/Foundatio.Redis/Cache/RedisCacheClientOptions.cs
user: login: TeddyAlbina
body: Add a check for Database, so when `IsCluster(this IConnectionMultiplexer muxer)` is true value must be -1 or 0.
created_at: 2025-05-15T07:55:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -35,15 +36,24 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
         options.ConnectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
+        
+        // Cluster config only valid between -1 and 0.
+        // -1 is default db parameter in stack exchange redis
+        if (!(options.Database >= -1 && options.Database <= 0 ) && options.ConnectionMultiplexer.IsCluster())
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: ejsmith
body: I don't want to be doing this kind of work in the constructor. I think we don't validate this. I'm not even 100% sure what is allowed in cluster mode. But I think we leave it up to the user.
created_at: 2025-05-15T16:39:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -35,15 +36,24 @@ public RedisCacheClient(RedisCacheClientOptions options)
         _timeProvider = options.TimeProvider ?? TimeProvider.System;
         options.Serializer ??= DefaultSerializer.Instance;
         _logger = options.LoggerFactory?.CreateLogger(typeof(RedisCacheClient)) ?? NullLogger.Instance;
+
         options.ConnectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
+        
+        // Cluster config only valid between -1 and 0.
+        // -1 is default db parameter in stack exchange redis
+        if (!(options.Database >= -1 && options.Database <= 0 ) && options.ConnectionMultiplexer.IsCluster())
path: src/Foundatio.Redis/Cache/RedisCacheClient.cs
user: login: TeddyAlbina
body: Humm... well i think you are right
created_at: 2025-05-16T03:04:06Z
author_association: CONTRIBUTOR

PR comments:
user: login: CLAassistant
created_at: 2025-05-14T15:15:38Z
body: [![CLA assistant check](https://cla-assistant.io/pull/badge/signed)](https://cla-assistant.io/FoundatioFx/Foundatio.Redis?pullRequest=101) <br/>All committers have signed the CLA.
author_association: NONE
user: login: CLAassistant
created_at: 2025-05-14T15:15:38Z
body: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/FoundatioFx/Foundatio.Redis?pullRequest=101) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/FoundatioFx/Foundatio.Redis?pullRequest=101) before we can accept your contribution.<br/><hr/>**Teddy ALBINA** seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please [add the email address used for this commit to your account](https://help.github.com/articles/why-are-my-commits-linked-to-the-wrong-user/#commits-are-not-linked-to-any-user).<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/FoundatioFx/Foundatio.Redis?pullRequest=101) it.</sub>
author_association: NONE
user: login: TeddyAlbina
created_at: 2025-05-15T01:46:15Z
body: Signer the CLA but it keeps saying it's not the case :/
author_association: CONTRIBUTOR
user: login: niemyjski
created_at: 2025-05-15T02:11:04Z
body: > Signer the CLA but it keeps saying it's not the case :/

No worries
author_association: MEMBER
user: login: TeddyAlbina
created_at: 2025-05-19T00:18:33Z
body: CLA signature fixed 🥳🥳🥳🥳
author_association: CONTRIBUTOR