ActionCable using Postgres listen/notify

Hi there,

The contributing guide suggests to write up feature requests on this out-of-the-way mailing list, and I couldn’t find a ticket or a blog post around using Postgres listen/notify with ActionCable (in fact the only thing I could find was: https://twitter.com/guilleiguaran/status/590526076536938496), so here I am.

Are there any objections to adding this?

Here’s an implementation I wrote with the Tubesock gem: Websockets with Postgres listen/notify and the Tubesock gem · GitHub

Sean Linsley

On a plane right now and can’t really dig in but the subject interests me. If you’re interested I have an ultra simple gem that uses AR for listen/notify in PG https://github.com/schneems/hey_you

Hey Richard, in the time between when this post was submitted and when it was approved for the mailing list, I made some progress reading through the existing implementation. There are some notes on the Twitter thread: https://twitter.com/seanlinsley/status/678654835982524416

The most important point is that the current code seems to create a new Redis connection for every websocket. It seems like Redis can handle that (the default max is 10k), but Postgres definitely can’t. My gist worked around that by creating a single thread to listen for new events, and trigger notifications to everyone that’s listening. It’d be quite difficult to keep the current approach and also support Postgres.

Thanks for the link to your repo. Reading through, I discovered that there’s a raw_connection method! Much better than accessing the instance variable like I was doing ^^’

I also refactored my gist, turning the one 20 line method into two 10 line methods. Though I haven’t actually tested that it still works ¯_(ツ)_/¯

Sean Linsley

Well, there’s a seemingly intractable problem: the current implementation allows you to disconnect all websockets for a given user. My implementation doesn’t provide a way to do that since each Rails server instance creates its own thread to listen for messages & notify the websockets it knows about.

https://github.com/rails/rails/blob/c3989819ea/actioncable/lib/action_cable/remote_connections.rb#L12

Hmm, perhaps it could be worked around by having each listener disconnect all websockets it knows about that match the given user.

Sean Linsley

We could create a PG channel that listens for a “disconnect” event perhaps.