feat(redis): support Redis Cluster via comma separated seed nodes - #1318
Open
bakiburakogun wants to merge 1 commit into
Open
feat(redis): support Redis Cluster via comma separated seed nodes#1318bakiburakogun wants to merge 1 commit into
bakiburakogun wants to merge 1 commit into
Conversation
The README recommends Redis for multi-node websocket deployments, but the client is built with createClient(), which does not follow MOVED redirections. Pointed at a Redis Cluster it connects and then fails roughly half of all operations at run time, depending on which slot a key hashes to. Treat a comma separated REDIS_URL as a list of cluster seed nodes and build a cluster client from it. Credentials given on the first seed are applied to the nodes discovered afterwards, since cluster discovery reports them without auth. A single URL keeps its existing behaviour. Signed-off-by: Baki Burak Öğün <63836730+bakiburakogun@users.noreply.github.com>
bakiburakogun
requested review from
grnd-alt,
hweihwang and
juliusknorr
as code owners
August 26, 2026 12:42
bakiburakogun
force-pushed
the
feat/redis-cluster-support
branch
from
August 30, 2026 02:13
9c8f3f7 to
1cff115
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1317
Summary
RedisAdapter.createRedisClient()builds a single-node client withcreateClient(), which does not followMOVEDredirections. Pointed at a Redis Cluster it connects successfully, the Socket.IO Redis Streams adapter sets up, and then roughly half of all operations fail at run time depending on which slot a key hashes to — a silent, partial failure rather than a clean one.This treats a comma separated
REDIS_URLas a list of cluster seed nodes:A single URL behaves exactly as before.
createCluster()comes from theredispackage already independencies, so there is no new requirement.Credentials given on the first seed are passed as cluster
defaults, because cluster discovery reports the remaining nodes without auth and they would otherwise be rejected.Testing
Against a 3-master / 3-replica cluster on a Debian 12 host, writing 40 keys:
createClient()pointed at one node (before)MOVED 8308 127.0.0.1:7002createCluster()with three seeds (after)Reads afterwards returned 40/40.
I also ran the real websocket server from this branch against that cluster, with
STORAGE_STRATEGY=redisand three seeds, and connected two Socket.IO clients with valid JWTs to the same board. Both receivedinit-room,room-user-changeanduser-joinedfor each other, so room state and the Streams adapter both work through the cluster client.One rough edge I did not fix
With a cluster client, the first command issued before the slot map is loaded throws rather than being queued, and I saw exactly one such error at startup:
It happened once, did not recur, and nothing downstream was affected — the server served boards normally afterwards. The cause is that
ServerServicestarts the connection without awaiting it (this.redisClient.connect().catch(...)), which a single-node client tolerates because it queues commands. Making startup await the connection would fix it properly, but that changes the constructor's shape, so I left it out of this PR rather than restructure startup on your behalf. Happy to follow up with that if you would like it.Note for administrators
Redis Cluster only has database 0, so the
/database_numbersuffix cannot be used to separate whiteboard keys from other users of the same cluster. I mentioned this in the README next to the cluster example.