Packages

macula

3.8.0
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
macula src macula_dist_system macula_dist_system.erl
Raw

src/macula_dist_system/macula_dist_system.erl

%%%-------------------------------------------------------------------
%%% @doc Macula Distribution System Supervisor.
%%%
%%% This supervisor manages the distribution subsystem components:
%%%
%%% - macula_dist_bridge_sup - Supervisor for relay tunnel bridges
%%% - macula_dist_discovery - Decentralized node discovery (replaces EPMD)
%%% - macula_cluster_strategy - Automatic cluster formation (optional)
%%%
%%% The bridge supervisor hosts `macula_dist_bridge' gen_server children
%%% (one per relay tunnel). When `macula_dist_system' is not started
%%% (standalone relay mode), `macula_dist_relay:advertise_dist_accept/0'
%%% starts the bridge supervisor on demand.
%%%
%%% Configuration options (in sys.config):
%%% dist_port - QUIC port (default 4433)
%%% discovery_type - mdns, dht, or both
%%% auto_cluster - automatically form cluster
%%%
%%% @copyright 2025 Macula.io Apache-2.0
%%% @end
%%%-------------------------------------------------------------------
-module(macula_dist_system).
-behaviour(supervisor).
%% API
-export([
start_link/0,
start_link/1,
start_dist_relay_client/2
]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%===================================================================
%%% API
%%%===================================================================
%% @doc Start the distribution system supervisor with default options.
-spec start_link() -> {ok, pid()} | {error, term()}.
start_link() ->
start_link(#{}).
%% @doc Start the distribution system supervisor with options.
-spec start_link(map()) -> {ok, pid()} | {error, term()}.
start_link(Opts) ->
supervisor:start_link({local, ?SERVER}, ?MODULE, Opts).
%% @doc Dynamically start the dist_relay_client under this supervisor.
%% Used by `macula:join_dist_relay/1' when the relay URL is chosen at
%% runtime rather than at application boot.
-spec start_dist_relay_client(binary() | string(), binary()) ->
{ok, pid()} | {error, term()}.
start_dist_relay_client(Url, NodeName) ->
ChildSpec = #{
id => macula_dist_relay_client,
start => {macula_dist_relay_client, start_link, [Url, NodeName]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [macula_dist_relay_client]
},
supervisor:start_child(?SERVER, ChildSpec).
%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================
%% @private
init(Opts) ->
SupFlags = #{
strategy => one_for_one,
intensity => 5,
period => 10
},
DiscoveryType = maps:get(discovery_type, Opts,
application:get_env(macula, discovery_type, both)),
AutoCluster = maps:get(auto_cluster, Opts,
application:get_env(macula, auto_cluster, false)),
%% Child specifications
Children = [
%% Bridge supervisor for relay distribution tunnels
#{
id => macula_dist_bridge_sup,
start => {macula_dist_bridge_sup, start_link, []},
restart => permanent,
shutdown => infinity,
type => supervisor,
modules => [macula_dist_bridge_sup]
},
%% Discovery service (always started)
#{
id => macula_dist_discovery,
start => {macula_dist_discovery, start_link, [#{
discovery_type => DiscoveryType
}]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [macula_dist_discovery]
}
] ++ maybe_cluster_strategy(AutoCluster, Opts)
++ maybe_dist_relay_client(Opts),
{ok, {SupFlags, Children}}.
%%%===================================================================
%%% Internal Functions
%%%===================================================================
%% @private Add cluster strategy child if auto_cluster is enabled
maybe_cluster_strategy(false, _Opts) ->
[];
maybe_cluster_strategy(true, Opts) ->
[
#{
id => macula_cluster_strategy,
start => {macula_cluster_strategy, start_link, [#{
topology => macula_cluster,
config => maps:get(cluster_config, Opts, #{})
}]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [macula_cluster_strategy]
}
].
%% @private Start the dist relay client if a dist_relay URL is configured.
%% The client maintains a persistent QUIC connection to a dist relay and
%% tunnels Erlang distribution traffic through it. Only one client per
%% node (registered as `macula_dist_relay_client').
maybe_dist_relay_client(Opts) ->
Url = maps:get(dist_relay_url, Opts,
application:get_env(macula, dist_relay_url, undefined)),
dist_relay_client_child(Url).
dist_relay_client_child(undefined) ->
[];
dist_relay_client_child(Url) ->
NodeName = atom_to_binary(node()),
[
#{
id => macula_dist_relay_client,
start => {macula_dist_relay_client, start_link, [Url, NodeName]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [macula_dist_relay_client]
}
].