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

Each websocket connection results into a brand new socket connection to redis hence it implicitly limits the maximum number of websockets that could be established by using this library #295

Open
sharrajesh opened this issue Apr 10, 2020 · 2 comments

Comments

@sharrajesh
Copy link

I have the need to support a very large number (100k+) of websocket connections from clients that do not send much but which needs to be notified by the server (DRF) once in a while when some conditions are met.

A the moment I am running DWR inside uwsgi with --gevent=2000 and 5 workers per kubernetes pod which is replicated 10 times i.e. 2000510=100000

The problem I ran into is that each websocket connection at the moment has to subscribe to a redis pubsub channel which results into a brand new socket connection on the redis.

Since redis is shared across all of our pod I cannot horizontally scale the number of supported websocket connections by just increasing my pods.

I was load testing my server with thor or sockme.

My cursory look at the code suggests that I should be able to leverage pipes/events (https://lat.sk/2015/02/multiple-event-waiting-python-3/) and fewer actual redis pubsub channels to avoid a very large number redis_fd (https://github.com/jrief/django-websocket-redis/blob/master/ws4redis/wsgi_server.py#L119).

Basically for each websocket, I will create a pipe and store the pipe handle and client-id into a worker process address space as a hash table entry.

When the server notify the redis pubsub channel and that greenlet/thread is fired running inside DWR it will get the client-id. Here I will enable the "event" based upon the client-id received. Which will enable the correct websocket loop to awaken.

I wanted to make sure before I go this direction, I talk to the most believable people here. Am I total nuts or is there a better way to support a very large number of socket connection by still using DWR.

[email protected]

@jrief
Copy link
Owner

jrief commented Apr 10, 2020

Well, another possibility would be to add more Redis servers and interconnect between them. The reason ws4redis opens a connection to Redis for each socket is, because it wants transparently pass that data through to the client. Adding an Id and using that for dispatching adds another layer of complexity and I'm unsure if we should do that.

One much more elegant solution would be to go async. This is something I wanted to to anyway, since greenlets are not the best solution for scaling threads. It would however require a complete redesign of ws4redis and presumably not add any additional value compared to the Channels project, except for it's much simpler setup and configuration.

@sharrajesh
Copy link
Author

Thank you @jrief

I am using this as a reference for my use case.

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

No branches or pull requests

2 participants