Search documentation of macula

# macula_peer (macula v0.44.2)

View Source

Macula Peer - Mesh Participant API (v0.7.0+).

This module provides the high-level API for mesh participants. Use this module to connect to a Macula mesh and communicate via pub/sub or RPC.

### Quick Start

       %% 1. Connect to a gateway
       {ok, Peer} = macula_peer:start_link(<<"https://gateway.example.com:9443">>, #{
           realm => <<"com.example.app">>
       }).

       %% 2. Subscribe to events
       ok = macula_peer:subscribe(Peer, <<"sensor.temperature">>, self()).

       %% 3. Publish an event
       ok = macula_peer:publish(Peer, <<"sensor.temperature">>, #{
           device_id => <<"sensor-001">>,
           celsius => 21.5
       }).

       %% 4. Call a remote service
       {ok, Result} = macula_peer:call(Peer, <<"calculator.add">>, #{a => 5, b => 3}).

       %% 5. Advertise a service
       ok = macula_peer:advertise(Peer, <<"calculator.add">>, fun(#{a := A, b := B}) ->
           #{result => A + B}
       end, #{ttl => 300}).

### Architecture

The peer acts as a facade/coordinator, delegating to specialized child processes: - `macula_connection`: QUIC transport layer (send/receive, encoding/decoding) - `macula_pubsub_handler`: Pub/sub message routing - `macula_rpc_handler`: RPC call/response handling - `macula_advertisement_manager`: DHT service advertisements

Renamed from macula_connection in v0.7.0 for clarity: - `macula_peer` = mesh participant (this module) - `macula_connection` = QUIC transport (low-level)

### Multi-Tenancy via Realms

Realms provide logical isolation for different applications:

       %% App 1
       {ok, Peer1} = macula_peer:start_link(GatewayUrl, #{realm => <<"com.app1">>}).

       %% App 2 (completely isolated from App 1)
       {ok, Peer2} = macula_peer:start_link(GatewayUrl, #{realm => <<"com.app2">>}).

# Summary

## Functions

advertise(Client, Procedure, Handler, Opts)

Advertise a service handler for a procedure.

call(Client, Procedure, Args)

Make an RPC call through this client (default timeout).

call(Client, Procedure, Args, Opts)

Make an RPC call through this client with options.

call_to(Client, TargetNodeId, Procedure, Args, Opts)

Make an RPC call to a specific target node.

discover_subscribers(Client, Topic)

Discover subscribers to a topic via DHT query.

get_node_id(Client)

Get the node ID of this peer.

publish(Client, Topic, Data)

Publish an event through this client (no options).

publish(Client, Topic, Data, Opts)

Publish an event through this client with options. This is fire-and-forget - returns ok immediately without blocking. Use QoS 1 in Opts if you need delivery confirmation.

start_link(Url, Opts)

Start a client connection to a Macula mesh.

stop(Client)

Stop the client connection.

subscribe(Client, Topic, Callback)

Subscribe to a topic through this client.

unadvertise(Client, Procedure)

Stop advertising a service.

unsubscribe(Client, SubRef)

Unsubscribe from a topic.

# Functions

# advertise(Client, Procedure, Handler, Opts)

    -spec advertise(pid(), binary(), fun((map()) -> {ok, term()} | {error, term()}), map()) ->
                       ok | {error, term()}.

Advertise a service handler for a procedure.

This makes the local handler available to other mesh nodes via DHT. The handler will be periodically re-advertised based on TTL.

# call(Client, Procedure, Args)

    -spec call(pid(), binary(), map() | list()) -> {ok, term()} | {error, term()}.

Make an RPC call through this client (default timeout).

# call(Client, Procedure, Args, Opts)

    -spec call(pid(), binary(), map() | list(), map()) -> {ok, term()} | {error, term()}.

Make an RPC call through this client with options.

# call_to(Client, TargetNodeId, Procedure, Args, Opts)

    -spec call_to(pid(), binary(), binary(), map() | list(), map()) -> {ok, term()} | {error, term()}.

Make an RPC call to a specific target node.

Unlike `call/4` which discovers any provider via DHT, this function sends the RPC directly to the specified target node.

# discover_subscribers(Client, Topic)

    -spec discover_subscribers(pid(), binary()) ->
                                  {ok, [#{node_id := binary(), endpoint := binary()}]} | {error, term()}.

Discover subscribers to a topic via DHT query.

# get_node_id(Client)

    -spec get_node_id(pid()) -> {ok, binary()} | {error, term()}.

Get the node ID of this peer.

# publish(Client, Topic, Data)

    -spec publish(pid(), binary(), map() | binary()) -> ok | {error, term()}.

Publish an event through this client (no options).

# publish(Client, Topic, Data, Opts)

    -spec publish(pid(), binary(), map() | binary(), map()) -> ok.

Publish an event through this client with options. This is fire-and-forget - returns ok immediately without blocking. Use QoS 1 in Opts if you need delivery confirmation.

# start_link(Url, Opts)

    -spec start_link(binary(), map()) -> {ok, pid()} | {error, term()}.

Start a client connection to a Macula mesh.

# stop(Client)

    -spec stop(pid()) -> ok.

Stop the client connection.

# subscribe(Client, Topic, Callback)

    -spec subscribe(pid(), binary(), fun((map()) -> ok)) -> {ok, reference()} | {error, term()}.

Subscribe to a topic through this client.

# unadvertise(Client, Procedure)

    -spec unadvertise(pid(), binary()) -> ok | {error, term()}.

Stop advertising a service.

Removes the local handler and stops advertising to the DHT.

# unsubscribe(Client, SubRef)

    -spec unsubscribe(pid(), reference()) -> ok | {error, term()}.

Unsubscribe from a topic.