Packages
macula
0.25.2
7.0.0
6.0.0
5.2.2
5.2.1
5.2.0
5.1.0
5.0.0
4.8.0
4.7.1
4.7.0
4.6.0
4.5.0
4.4.10
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.1
4.3.0
4.2.9
4.2.8
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.1
4.1.0
4.0.0
3.16.0
3.15.3
3.15.2
3.15.1
3.14.0
3.13.0
3.12.1
3.12.0
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.9.0
3.8.0
3.7.0
3.5.0
3.4.0
3.3.0
3.2.0
3.1.0
3.0.0
2.1.1
2.1.0
2.0.0
1.5.2
1.5.1
1.4.30
1.4.29
1.4.28
1.4.27
1.4.26
1.4.25
1.4.24
1.4.23
1.4.22
1.4.21
1.4.20
1.4.19
1.4.18
1.4.17
1.4.16
1.4.15
1.4.14
1.4.13
1.4.11
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.2.0
1.1.0
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.48.6
0.48.5
0.48.4
0.48.3
0.48.2
0.48.1
0.48.0
0.47.1
0.47.0
0.46.3
0.46.1
0.46.0
0.45.3
0.45.2
0.45.1
0.45.0
0.44.2
0.44.1
0.44.0
0.43.3
0.43.2
0.43.1
0.43.0
0.42.9
0.42.8
0.42.7
0.42.6
0.42.5
0.42.4
0.42.3
0.42.2
0.42.1
0.42.0
0.41.1
0.41.0
0.40.1
0.40.0
0.39.9
0.39.8
0.39.7
0.39.6
0.39.5
0.39.4
0.39.3
0.39.2
0.39.1
0.39.0
0.38.8
0.38.7
0.38.6
0.38.5
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.7
0.37.6
0.37.5
0.37.4
0.37.3
0.37.2
0.37.1
0.37.0
0.36.6
0.36.5
0.36.4
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.1
0.34.0
0.33.1
0.33.0
0.32.5
0.32.4
0.32.3
0.32.2
0.32.1
0.32.0
0.31.9
0.31.8
0.31.7
0.31.6
0.31.5
0.31.4
0.31.3
0.31.2
0.31.1
0.31.0
0.30.10
0.30.9
0.30.8
0.30.7
0.30.6
0.30.5
0.30.4
0.30.3
0.30.2
0.30.1
0.30.0
0.29.0
0.28.3
0.28.2
0.28.1
0.28.0
0.27.1
0.27.0
0.26.1
0.26.0
0.25.6
0.25.5
0.25.4
0.25.3
0.25.2
0.25.1
0.25.0
0.24.6
0.24.5
0.24.4
0.24.3
0.24.2
0.24.1
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.12
0.22.11
0.22.10
0.22.9
0.22.8
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.7
0.21.6
0.21.5
0.21.4
0.21.2
0.21.1
0.21.0
0.20.25
0.20.24
0.20.23
0.20.22
0.20.21
0.20.20
0.20.19
0.20.18
0.20.17
0.20.16
0.20.15
0.20.14
0.20.13
0.20.12
0.20.11
0.20.10
0.20.9
0.20.8
0.20.7
0.20.6
0.20.5
0.20.3
0.20.2
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.12.6
0.12.5
0.12.3
0.11.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.30
0.7.29
0.7.28
0.7.27
0.7.26
0.7.25
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.4
0.3.3
0.3.2
0.3.1
Macula HTTP/3 Mesh SDK — connect, subscribe, publish, call, advertise
Current section
Files
Jump to
Current section
Files
src/macula_peers_sup.erl
%%%-------------------------------------------------------------------
%% @doc Macula Peers Supervisor.
%%
%% This supervisor manages dynamic peer connections using a
%% simple_one_for_one strategy. Each peer connection gets its own
%% macula_peer_system supervisor with dedicated handlers.
%%
%% Architecture (v0.8.5):
%% - One macula_peers_sup instance per Macula node
%% - Dynamically adds/removes macula_peer_system children
%% - Each child = one peer connection
%% - simple_one_for_one strategy for efficient scaling
%%
%% Usage:
%% <pre>
%% %% Start new peer connection
%% {ok, PeerPid} = macula_peers_sup:start_peer(Url, Opts).
%%
%% %% List all active peers
%% Peers = macula_peers_sup:list_peers().
%%
%% %% Count active peers
%% Count = macula_peers_sup:count_peers().
%%
%% %% Stop peer connection
%% ok = macula_peers_sup:stop_peer(PeerPid).
%% </pre>
%%
%% @end
%%%-------------------------------------------------------------------
-module(macula_peers_sup).
-behaviour(supervisor).
-include_lib("kernel/include/logger.hrl").
%% API
-export([
start_link/0,
start_peer/2,
stop_peer/1,
list_peers/0,
count_peers/0
]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%=============================================================================
%%% API Functions
%%%=============================================================================
%%------------------------------------------------------------------------------
%% @doc Start the peers supervisor.
%%
%% Called by macula_root during application startup.
%% Registers the supervisor with the local name macula_peers_sup.
%%
%% @end
%%------------------------------------------------------------------------------
-spec start_link() -> {ok, pid()} | {error, term()}.
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%%------------------------------------------------------------------------------
%% @doc Start a new peer connection.
%%
%% Creates a new macula_peer_system supervisor for the peer at the given URL.
%% The peer system will manage the connection lifecycle and all peer-specific
%% handlers (pubsub, rpc, advertisements).
%%
%% @param Url Peer URL (e.g., "https://peer.example.com:4433")
%% @param Opts Connection options (realm, etc.)
%% @returns {ok, PeerPid} | {error, Reason}
%% @end
%%------------------------------------------------------------------------------
-spec start_peer(Url :: binary(), Opts :: map()) -> {ok, pid()} | {error, term()}.
start_peer(Url, Opts) when is_binary(Url), is_map(Opts) ->
supervisor:start_child(?SERVER, [Url, Opts]);
start_peer(Url, Opts) when is_list(Url), is_map(Opts) ->
start_peer(list_to_binary(Url), Opts).
%%------------------------------------------------------------------------------
%% @doc Stop a peer connection.
%%
%% Gracefully terminates the macula_peer_system supervisor for the given peer.
%% This will clean up all peer handlers and close the connection.
%%
%% @param PeerPid PID of the peer system supervisor to stop
%% @returns ok | {error, not_found}
%% @end
%%------------------------------------------------------------------------------
-spec stop_peer(PeerPid :: pid()) -> ok | {error, term()}.
stop_peer(PeerPid) when is_pid(PeerPid) ->
case supervisor:terminate_child(?SERVER, PeerPid) of
ok -> ok;
{error, not_found} -> {error, not_found};
{error, Reason} -> {error, Reason}
end.
%%------------------------------------------------------------------------------
%% @doc List all active peer connections.
%%
%% Returns a list of PIDs for all currently running macula_peer_system
%% supervisors.
%%
%% @returns [pid()]
%% @end
%%------------------------------------------------------------------------------
-spec list_peers() -> [pid()].
list_peers() ->
Children = supervisor:which_children(?SERVER),
[Pid || {_Id, Pid, _Type, _Modules} <- Children, is_pid(Pid)].
%%------------------------------------------------------------------------------
%% @doc Count active peer connections.
%%
%% Returns the number of currently running macula_peer_system supervisors.
%%
%% @returns non_neg_integer()
%% @end
%%------------------------------------------------------------------------------
-spec count_peers() -> non_neg_integer().
count_peers() ->
length(list_peers()).
%%%=============================================================================
%%% Supervisor Callbacks
%%%=============================================================================
%%------------------------------------------------------------------------------
%% @doc Initialize the peers supervisor.
%%
%% Sets up a simple_one_for_one supervisor for macula_peer_system children.
%% Each child will be started with dynamic arguments (Url, Opts).
%%
%% Strategy: simple_one_for_one
%% - Efficient for managing many similar children
%% - Children started/stopped dynamically
%% - All children use same child spec template
%%
%% Restart Strategy: temporary
%% - Peer connections don't auto-restart on crash
%% - Application decides when to reconnect
%% - Prevents reconnection storms
%%
%% @end
%%------------------------------------------------------------------------------
init([]) ->
?LOG_INFO("Starting Peers Supervisor (simple_one_for_one)"),
SupFlags = #{
strategy => simple_one_for_one,
intensity => 10, % Max 10 restarts
period => 60 % In 60 seconds
},
%% Child spec template for macula_peer_system
%% Actual Url and Opts will be passed to start_peer/2
ChildSpec = #{
id => macula_peer_system, % Template ID (not used for simple_one_for_one)
start => {macula_peer_system, start_link, []}, % Args appended by start_child
restart => temporary, % Don't auto-restart failed peers
shutdown => 5000, % 5 second shutdown timeout
type => supervisor, % macula_peer_system is a supervisor
modules => [macula_peer_system]
},
{ok, {SupFlags, [ChildSpec]}}.