Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom Redis socket.io adapter #4596

Merged
merged 4 commits into from
Dec 15, 2020

Conversation

GaryWilber
Copy link
Contributor

Alfred currently uses the socket.io-redis adapter for fluid operation pubsub. Each socket.io server (Alfred) subscribes to a Redis pattern subscription called "socketio#/fluid#*”. For every op, the broadcaster lambda publishes messages to a topic that looks like “socketio#/fluid#{tenantId}/{documentId}#op”.

This means that a single broadcast will be received by every single machine that subscribed for socketio#/fluid#*. If we have a region with 100 instances of Alfred and have 2 users connected to the same document on 2 different machines, their ops will be received by 98 other Alfred’s – this is terrible when horizontally scaling the service. It also has a significant impact on the performance of Redis.

This custom adapter introduces a subscription per “room” (tenant/document id pair). This means that in the above scenario with 100 instances and 2 clients connected to a document, their ops would only be broadcasted to the 2 Alfred instances that actually had clients connected for that document.

Differences between this and socket.io-redis:

This PR only adds the implementation for this new socket.io adapter. It does not integrate it into Alfred's socket.io server. That will be done in a separate PR.

References:

// queue a health check even though we are not currrently subscribed
// the fact that this health check timer is still running means we still want to be subscribed to the room
// likely caused by a redis disconnection & a reconnection is in progress
this.queueRoomHealthCheck(room);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like queueRoomHealthCheck() calls runRoomHealthCheck(), which in turn calls queueRoomHealthCheck() again - it looks recursive. If that's the case, is there any chance the recursion never ends and we run out of resources or something similar? Apologies if I'm missing something obvious :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is recursive but it will eventually end. When all clients leave a room, it triggers an unsubscribe call for that channel. And so the queueRoomHealthCheck method will stop because RedisSocketIoAdapter.options.subConnection.isSubscribed(room) will return false

@GaryWilber GaryWilber merged commit 07690ad into microsoft:main Dec 15, 2020
@GaryWilber GaryWilber deleted the redis_socket_io_adapter branch December 15, 2020 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants