Hello, cluster
View SourceThis is the smallest end-to-end exercise: two nodes, one registered service, one cross-node message. If you have read Getting started, you have already done most of this; the goal here is to put it in one self-contained tutorial.
Prerequisites
- Erlang/OTP 27 or later.
rebar3.- An empty project (or any project where you can add a dependency).
Step 1: add the dependency
In your rebar.config:
{deps, [
{barrel_p2p, "0.1.0"}
]}.
{ex_doc, [
{extras, [<<"README.md">>]}
]}.Fetch and compile:
rebar3 get-deps
rebar3 compile
Step 2: minimal sys.config
config/sys.config:
[
{barrel_p2p, [
{active_size, 5},
{passive_size, 30},
{listen_port, 9100},
{auth_enabled, true},
{auth_trust_mode, tofu}
]}
].Step 3: start two nodes
In one terminal:
ERL_AFLAGS="-proto_dist barrel_p2p -epmd_module barrel_p2p_epmd -start_epmd false" \
rebar3 shell --config config/sys.config --sname node1
In another:
ERL_AFLAGS="-proto_dist barrel_p2p -epmd_module barrel_p2p_epmd -start_epmd false" \
rebar3 shell --config config/sys.config --sname node2
On node2:
1> barrel_p2p:join('node1@yourhost').
ok
2> barrel_p2p:active_view().
['node1@yourhost']Replace yourhost with the short hostname from
inet:gethostname/0. Both shells need to resolve the same
hostname.
Step 4: register a service
On node1:
1> Pid = spawn(fun() -> timer:sleep(infinity) end).
<0.123.0>
2> barrel_p2p:register_service(my_worker, Pid, #{role => worker}).
okOn node2, after a moment:
3> {ok, _Node, FoundPid} = barrel_p2p:whereis_service(my_worker).
{ok, 'node1@yourhost', <0.123.0>}
4> FoundPid ! hello.
helloThe whereis_service/1 call returns {ok, Node, Pid} for a
remote service. The send-bang uses standard Erlang distribution
on top of the barrel_p2p dist channel.
Step 5: subscribe to events
Still on node2:
5> barrel_p2p:subscribe_services().
okNow have node1 register and unregister a service:
%% On node1
3> barrel_p2p:register_service(another, #{}).
4> barrel_p2p:unregister_service(another).On node2, the listening process receives:
{barrel_p2p_service_event, {service_registered, another, 'node1@yourhost'}}
{barrel_p2p_service_event, {service_unregistered, another, 'node1@yourhost'}}The subscription is per-pid. Use it to invalidate caches or to trigger application-level reactions to cluster changes.
What this tutorial covered
- Booting a node with
-proto_dist barrel_p2p. - Joining a peer with
barrel_p2p:join/1. - Registering a service with metadata.
- Discovering the service from another node.
- Subscribing to service events.
Next
- Distributed chat — the same primitives applied to a small chat application.
- Service registry concept — how registration and discovery work under the hood.
- Cluster membership concept — how HyParView keeps the membership bounded.