Packages
macula
0.22.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
Current section
Files
src/macula_platform_system/macula_platform_system.erl
%%%-------------------------------------------------------------------
%%% @doc Macula Platform System Supervisor.
%%%
%%% This supervisor manages the platform layer services that provide
%%% distributed coordination primitives for workloads.
%%%
%%% Platform Services (v0.15.0+):
%%% - CRDT-based shared state (LWW-Register, OR-Set, G-Counter, PN-Counter)
%%% - Gossip-based state synchronization (macula_gossip)
%%% - Coordination Primitives (locks, barriers, etc. - future)
%%%
%%% Architecture:
%%% macula_root
%%% ├── [infrastructure: routing, bootstrap, gateway, peers]
%%% └── macula_platform_system (this module)
%%% └── macula_gossip (CRDT state synchronization)
%%%
%%% Configuration:
%%% - gossip_enabled: Enable gossip protocol (default: true)
%%% - gossip_push_interval: Push interval in ms (default: 1000)
%%% - gossip_anti_entropy_interval: Anti-entropy interval in ms (default: 30000)
%%% - gossip_fanout: Number of peers per gossip round (default: 3)
%%%
%%% Note: Ra/Raft was removed in v0.14.0. Macula uses CRDTs for
%%% eventually-consistent state management without leader election.
%%% See architecture/ROADMAP.md for details.
%%% @end
%%%-------------------------------------------------------------------
-module(macula_platform_system).
-behaviour(supervisor).
-include_lib("kernel/include/logger.hrl").
-export([start_link/1]).
-export([init/1]).
%% API for accessing gossip server
-export([
get_gossip_pid/0,
is_gossip_enabled/0
]).
-define(SERVER, ?MODULE).
%%====================================================================
%% API functions
%%====================================================================
%% @doc Start the platform system supervisor.
-spec start_link(map()) -> {ok, pid()} | {error, term()}.
start_link(Config) ->
supervisor:start_link({local, ?SERVER}, ?MODULE, Config).
%% @doc Get the PID of the gossip server.
-spec get_gossip_pid() -> {ok, pid()} | {error, not_started}.
get_gossip_pid() ->
case whereis(macula_gossip) of
undefined -> {error, not_started};
Pid -> {ok, Pid}
end.
%% @doc Check if gossip is enabled.
-spec is_gossip_enabled() -> boolean().
is_gossip_enabled() ->
case get_gossip_pid() of
{ok, _} -> true;
_ -> false
end.
%%====================================================================
%% Supervisor callbacks
%%====================================================================
%% @doc Initialize the platform system supervisor.
%% Starts the gossip server if enabled (default: true).
init(Config) ->
?LOG_INFO("Starting Macula Platform System (CRDT-based, masterless)"),
NodeId = maps:get(node_id, Config, <<"unknown">>),
Realm = maps:get(realm, Config, <<"unknown">>),
?LOG_INFO("Node ID: ~s", [NodeId]),
?LOG_INFO("Realm: ~s", [Realm]),
SupFlags = #{
strategy => one_for_one,
intensity => 5,
period => 10
},
%% Check if gossip is enabled (default: true)
GossipEnabled = gossip_enabled(Config),
ChildSpecs = case GossipEnabled of
true ->
GossipConfig = build_gossip_config(Config),
?LOG_INFO("Gossip protocol enabled with config: ~p", [GossipConfig]),
[gossip_child_spec(GossipConfig)];
false ->
?LOG_INFO("Gossip protocol disabled"),
[]
end,
?LOG_INFO("Platform system initialized (no Ra/Raft, using CRDTs + Gossip)"),
{ok, {SupFlags, ChildSpecs}}.
%%====================================================================
%% Internal functions
%%====================================================================
%% @private Check if gossip is enabled via config or environment.
-spec gossip_enabled(map()) -> boolean().
gossip_enabled(Config) ->
case maps:get(gossip_enabled, Config, undefined) of
undefined ->
%% Check environment variable
case os:getenv("MACULA_GOSSIP_ENABLED") of
"false" -> false;
"0" -> false;
_ -> true % Default: enabled
end;
Enabled ->
Enabled
end.
%% @private Build gossip configuration from platform config.
-spec build_gossip_config(map()) -> map().
build_gossip_config(Config) ->
#{
node_id => maps:get(node_id, Config, undefined),
realm => maps:get(realm, Config, <<"default">>),
push_interval => maps:get(gossip_push_interval, Config, 1000),
anti_entropy_interval => maps:get(gossip_anti_entropy_interval, Config, 30000),
fanout => maps:get(gossip_fanout, Config, 3),
peers => maps:get(gossip_peers, Config, []),
send_fn => maps:get(gossip_send_fn, Config, default_send_fn())
}.
%% @private Create child spec for gossip server.
-spec gossip_child_spec(map()) -> supervisor:child_spec().
gossip_child_spec(GossipConfig) ->
#{
id => macula_gossip,
start => {macula_gossip, start_link, [GossipConfig]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [macula_gossip]
}.
%% @private Default send function (no-op, to be replaced by actual implementation).
-spec default_send_fn() -> fun((binary(), term()) -> ok).
default_send_fn() ->
fun(_PeerNodeId, _Msg) ->
%% TODO: Integrate with macula_gateway for actual message sending
%% For now, this is a no-op. The actual send function will be
%% provided by the gateway system when gossip messages need to
%% be routed to other nodes.
ok
end.