9

I'm trying to compare Phoenix Channels with the new Rails ActionCable when it comes to working with WebSockets.

For some context, ActionCable uses Redis to handle PubSub when broadcasting a message to all clients. Example scenario: 1 of 3 rails processes on a separate node will be able to broadcast to clients connected on all web servers. This is done by hitting Redis which in turn publishes to all rails servers who then push to all their connected clients.

I recently read about the 2 million websocket connections achieved by Phoenix websocket connections.

Also found this gem: The Phoenix 1.0 release notes mention this regarding channels:

Even on a cluster of machines, your messages are broadcasted across the nodes automatically

How is Phoenix able to broadcast to clients across nodes? Is it using mailboxes and/or some other interprocess communication under the hood?

This is similar to question 2) in this post.

Thanks!

Community
  • 1
  • 1
dimroc
  • 1,172
  • 1
  • 16
  • 26

1 Answers1

17

Phoenix's PubSub layer is implemented solely with the standard library. The Erlang VM's concurrency model is distributed out of the box. So the mailbox/messaging model Just Works wether you are sending a message locally send(some_local_pid, :a_message) or globally send(some_pid_on_another_machine, :a_message). This is one of the amazing things about Elixir and Erlang that allows Phoenix to shed dependencies like Redis. If you're curious how Phoenix's PubSub system leverages these features in its implementation, see this blog post:

http://www.zohaib.me/guts-of-phoenix-channels/?utm_campaign=elixir_radar_28&utm_medium=email&utm_source=RD+Station

tldr; we use local ETS tables to hold PubSub subscriptions for processes local to a Node, and we broadcast across nodes using a single :pg2 group that each PubSub.Local server is a member of. When PubSub.Local server receives a broadcast, it forwards the message to all subscribers locally by looking up the local ETS subscriptions. The actual IPC details and node<->node communication is handled entirely by the runtime.

Chris McCord
  • 8,020
  • 1
  • 37
  • 26
  • Thanks! This all sounds great. I'm curious how the web servers know about each other to enable peer broadcast but I'll save that for my own research. It seems like this model would also be applicable for a worker queue. A true phoenix background worker framework wouldn't use redis like sidekiq or [exq](https://github.com/akira/exq) but would use this approach. – dimroc Dec 15 '15 at 16:51
  • 3
    This is for the next reader passing by. Each node (in this case webserver) knows how to communicate to the other nodes because they deployed the application as a distributed system. Click the link below for more details: http://benjamintan.io/blog/2014/05/25/connecting-elixir-nodes-on-the-same-lan/ – dimroc Dec 15 '15 at 19:58
  • Thanks Chris for the explanation. I was checking `pg2` documents and seems scheduled to be removed in OTP 24 with the introduced `pg` replacement, Does it effect on Phoenix? https://erlang.org/doc/man/pg2.html – Masoud Apr 12 '21 at 06:46