Distributed Erlang

Pids, links, and monitors work transparently across nodes.

33.1 Starting nodes

erl -sname alice -setcookie secret
erl -sname bob   -setcookie secret
# fully qualified: erl -name [email protected] -setcookie secret
(bob@host)1> net_adm:ping('alice@host').
pong
(bob@host)2> nodes().
['alice@host']
(bob@host)3> node().
'bob@host'

33.2 Remote operations

Pids, links, and monitors work transparently across nodes.

spawn('alice@host', fun() -> io:format("on ~p~n", [node()]) end),
{registered_name, 'alice@host'} ! Msg,
rpc:call('alice@host', erlang, system_info, [process_count]),
erpc:call('alice@host', lists, sum, [[1, 2, 3]]),         % OTP 23+, preferred
erpc:multicall(nodes(), erlang, memory, [total]),
rpc:multicall(nodes(), M, F, A),
monitor_node('alice@host', true),                        % {nodedown, Node}
net_kernel:monitor_nodes(true),
erlang:disconnect_node('alice@host').

33.3 Security & infrastructure

Cookie: shared secret for authentication (~/.erlang.cookie, erlang:set_cookie/2). Not encryption!

EPMD: port mapper daemon on TCP 4369; nodes listen on dynamic ports (restrict with inet_dist_listen_min/max).

TLS distribution: -proto_dist inet_tls with certificates for untrusted networks.

Hidden nodes (-hidden) don't join the full mesh.

Default topology is a fully connected mesh → practical limits around 50–200 nodes; beyond that use Partisan or hierarchical designs.

33.4 Global names & process groups

global:register_name(leader, self()),
global:whereis_name(leader),
global:send(leader, Msg),
gen_server:call({global, leader}, ping),

pg:start_link(),                % pg (OTP 23+) replaced pg2
pg:join(workers, self()),
pg:get_members(workers),
pg:monitor(workers).            % OTP 25+

33.5 Handling netsplits

Distributed systems must handle partitions: use monitors (nodedown), idempotent operations, CRDTs, or consensus libraries (ra — Raft, used by RabbitMQ quorum queues; riak_core for consistent hashing / dynamo-style systems).