Socketelx.Backend.Distributed (socketelx v0.4.3)

Copy Markdown View Source

Experimental. Lets several Socketelx nodes behave as one using only Erlang's built-in clustering, with no Redis. Enable it with cluster: :erlang (or SOCKETELX_CLUSTER=erlang); see the Multi-server guide for setup.

How it works

ConcernHow
Connecting nodesStandard distributed Erlang. Your app may already cluster (libcluster, a Phoenix cluster), or set :cluster_nodes / :cluster_dns and the nodes find each other.
BroadcastsEach node delivers to its own sockets, then sends the message straight to the other nodes' relay processes (:pg process groups). No central point is involved.
Presence and occupancyOne leader (the smallest member pid, so every node agrees without voting) holds the cluster-wide picture and decides, serially, whether a join is a user's first connection or a leave their last. That is what makes member_added, member_removed, channel_occupied and channel_vacated fire once for the whole cluster. Every other node keeps a standby copy.
Channel lists and countsAsked of every node on demand and combined.

Failure behaviour

  • A node dies or is cut off: within about a second the leader drops what that node owned and announces the departures once.
  • The leader's node dies: the next member takes over from its standby copy, asks every live node what it owns, then announces the departures of anything owned by dead nodes. Operations wait briefly (up to about two seconds) for the new leader; broadcasts between surviving nodes keep flowing throughout.
  • A network partition: each side carries on with its own leader and clients. When the partition heals, the sides are merged and the returning node's members and channels are announced as joins.
  • Delivery is at-most-once, like Pusher itself.

Limits you should know about

  • The leader handles every subscribe, unsubscribe and presence change in the cluster, so this mode suits tens of thousands of connections, not millions. Use the Redis backend if you need the most headroom.
  • Detecting a node that died without closing its connection takes as long as the Erlang net_ticktime (60 seconds by default). Lower it with -kernel net_ticktime 15 (in ERL_AFLAGS) if you need faster cleanup.
  • Distributed Erlang is unauthenticated apart from a shared cookie. Never expose the Erlang ports (4369 and the distribution port range) to the internet, and set RELEASE_COOKIE to a long random secret.
  • Redis and this mode are alternatives; configure one, not both.