Packages
macula
0.7.25
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_root.erl
%%%-------------------------------------------------------------------
%% @doc Macula Application Root Supervisor.
%%
%% This is the top-level supervisor for the Macula application.
%% It manages core infrastructure and optionally starts gateway services.
%%
%% Supervision Hierarchy:
%% <pre>
%% macula_root (this module - application root)
%% ├── macula_routing_server (core DHT infrastructure)
%% └── macula_gateway_system (optional - gateway subsystem)
%% ├── macula_gateway_health
%% ├── macula_gateway_diagnostics
%% ├── macula_gateway_quic_server
%% ├── macula_gateway
%% └── macula_gateway_workers_sup
%% </pre>
%%
%% Naming Convention (v0.7.10+):
%% - _root: Application root supervisor (one per application)
%% - _system: Subsystem root supervisors (gateway, peer, etc.)
%% - _sup: Worker supervisors (workers_sup)
%%
%% @end
%%%-------------------------------------------------------------------
-module(macula_root).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%% sup_flags() = #{strategy => strategy(), % optional
%% intensity => non_neg_integer(), % optional
%% period => pos_integer()} % optional
%% child_spec() = #{id => child_id(), % mandatory
%% start => mfargs(), % mandatory
%% restart => restart(), % optional
%% shutdown => shutdown(), % optional
%% type => worker(), % optional
%% modules => modules()} % optional
init([]) ->
SupFlags = #{
strategy => one_for_one,
intensity => 10,
period => 5
},
%% Core infrastructure (always started)
CoreSpecs = get_core_child_specs(),
%% Gateway services (conditionally started)
GatewaySpecs = maybe_start_gateway(),
ChildSpecs = CoreSpecs ++ GatewaySpecs,
{ok, {SupFlags, ChildSpecs}}.
%% internal functions
%% @private
%% @doc Get core infrastructure child specs (always started, even in embedded mode).
%% The routing server is essential for DHT operations in any mode.
get_core_child_specs() ->
io:format("Starting Macula core infrastructure (routing server)~n"),
[
%% DHT routing server (essential for all DHT operations)
#{
id => macula_routing_server,
start => {macula_routing_server, start_link, [get_node_id(), get_routing_config()]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [macula_routing_server]
}
].
%% @private
%% @doc Conditionally start gateway services based on configuration.
%% Set {start_gateway, false} in config to disable gateway (for client-only mode).
maybe_start_gateway() ->
case application:get_env(macula, start_gateway, true) of
true ->
%% Read gateway configuration from environment or config
Port = get_gateway_port(),
Realm = get_gateway_realm(),
HealthPort = get_health_port(),
io:format("Starting Macula Gateway on port ~p (realm: ~s)~n", [Port, Realm]),
io:format("Starting health check server on port ~p~n", [HealthPort]),
[
%% Gateway system supervisor (manages all gateway components)
#{
id => macula_gateway_system,
start => {macula_gateway_system, start_link, [[
{port, Port},
{realm, Realm},
{health_port, HealthPort}
]]},
restart => permanent,
shutdown => infinity,
type => supervisor,
modules => [macula_gateway_system]
}
];
false ->
io:format("Gateway auto-start disabled (client-only mode)~n"),
[]
end.
%% @private
%% @doc Get gateway port from environment variable or config.
get_gateway_port() ->
case os:getenv("GATEWAY_PORT") of
false ->
application:get_env(macula, gateway_port, 9443);
PortStr ->
list_to_integer(PortStr)
end.
%% @private
%% @doc Get gateway realm from environment variable or config.
get_gateway_realm() ->
case os:getenv("MACULA_REALM") of
false ->
application:get_env(macula, gateway_realm, <<"com.example.realm">>);
RealmStr ->
list_to_binary(RealmStr)
end.
%% @private
%% @doc Get health check port from environment variable or config.
get_health_port() ->
case os:getenv("HEALTH_PORT") of
false ->
application:get_env(macula, health_port, 8080);
PortStr ->
list_to_integer(PortStr)
end.
%% @private
%% @doc Get node ID for DHT routing (32-byte identifier).
get_node_id() ->
%% Try environment variable first, then config, finally generate one
case os:getenv("NODE_ID") of
false ->
case application:get_env(macula, node_id) of
{ok, NodeId} when is_binary(NodeId), byte_size(NodeId) == 32 ->
NodeId;
_ ->
%% Generate a random 32-byte node ID
crypto:strong_rand_bytes(32)
end;
NodeIdStr ->
list_to_binary(NodeIdStr)
end.
%% @private
%% @doc Get DHT routing configuration.
get_routing_config() ->
#{
k => application:get_env(macula, dht_k, 20), %% Kademlia K parameter
alpha => application:get_env(macula, dht_alpha, 3) %% Concurrent queries
}.