macula_peer (macula v0.20.3)

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 a service handler for a procedure.

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

Make an RPC call through this client with options.

Make an RPC call to a specific target node.

Discover subscribers to a topic via DHT query.

Get the node ID of this peer.

Publish an event through this client (no options).

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 a client connection to a Macula mesh.

Stop the client connection.

Subscribe to a topic through this client.

Stop advertising a service.

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.