Search documentation of macula

# macula_cluster (macula v4.4.1)

View Source

Cluster management utilities for Macula platform.

This module provides cluster infrastructure functions that other applications (like bc_gitops) can delegate to when running on the Macula platform.

### Distribution

The `ensure_distributed/0` function ensures the node is running in distributed mode. If not already distributed, it starts distribution with a generated node name.

### Cookie Management

Cookies are resolved in this priority order: 1. Application env: `{macula, [{cookie, CookieValue}]}` 2. Environment variable: `MACULA_COOKIE` or `RELEASE_COOKIE` 3. User's ~/.erlang.cookie file 4. Auto-generated (persisted to ~/.erlang.cookie)

### Node Monitoring

The `monitor_nodes/0` and `unmonitor_nodes/0` functions wrap `net_kernel:monitor_nodes/1` for subscribing to nodeup/nodedown messages.

### bc_gitops Integration

When bc_gitops is running on the Macula platform, it detects these exports and delegates clustering operations here. This allows Macula to own cluster infrastructure while bc_gitops remains usable standalone.

# Summary

## Functions

cookie_file_path()

Get the path to the cookie file.

ensure_distributed()

Ensure this node is running in distributed mode.

get_cookie()

Get the Erlang cookie for the cluster.

get_hostname()

Get the short hostname of this machine.

is_clustered()

Check if auto-clustering is currently active.

is_distributed()

Check if this node is running in distributed mode.

monitor_nodes()

Subscribe to node up/down events.

nodes()

Get list of connected cluster nodes.

read_cookie_file()

Read cookie from ~/.erlang.cookie file.

resolve_cookie()

Resolve the cookie from various sources.

set_cookie(Cookie)

Set the Erlang cookie for this node and persist it.

start_cluster()

Start automatic cluster formation with default options.

start_cluster(Opts)

Start automatic cluster formation with options.

stop_cluster()

Stop automatic cluster formation.

unmonitor_nodes()

Unsubscribe from node up/down events.

# Functions

# cookie_file_path()

    -spec cookie_file_path() -> file:filename().

Get the path to the cookie file.

# ensure_distributed()

    -spec ensure_distributed() -> ok | {error, term()}.

Ensure this node is running in distributed mode.

If the node is already distributed, returns `ok` immediately. Otherwise, starts distribution with a generated node name in the format `macula_host@hostname`.

Examples:

      ok = macula_cluster:ensure_distributed().

# get_cookie()

    -spec get_cookie() -> atom().

Get the Erlang cookie for the cluster.

Resolves the cookie from various sources in priority order. If no cookie is found, generates and persists a new one.

Resolution Order: 1. Application env: `{macula, [{cookie, CookieValue}]}` 2. Environment variable: `MACULA_COOKIE` or `RELEASE_COOKIE` 3. User's ~/.erlang.cookie file 4. Auto-generated (persisted to ~/.erlang.cookie)

Examples:

      Cookie = macula_cluster:get_cookie().

# get_hostname()

    -spec get_hostname() -> string().

Get the short hostname of this machine.

Examples:

      "myhost" = macula_cluster:get_hostname().

# is_clustered()

    -spec is_clustered() -> boolean().

Check if auto-clustering is currently active.

Returns `true` if any cluster strategy is running (gossip, static, or DHT).

# is_distributed()

    -spec is_distributed() -> boolean().

Check if this node is running in distributed mode.

# monitor_nodes()

    -spec monitor_nodes() -> ok.

Subscribe to node up/down events.

After calling this function, the calling process will receive `{nodeup, Node}` and `{nodedown, Node}` messages when nodes join or leave the cluster.

Examples:

      ok = macula_cluster:monitor_nodes().
      receive
          {nodeup, Node} -> io:format("Node joined: ~p~n", [Node]);
          {nodedown, Node} -> io:format("Node left: ~p~n", [Node])
      end.

# nodes()

    -spec nodes() -> [atom()].

Get list of connected cluster nodes.

Returns all nodes connected to this node via Erlang distribution.

Examples:

      Nodes = macula_cluster:nodes().
      %% => ['node1@host1', 'node2@host2']

# read_cookie_file()

    -spec read_cookie_file() -> {ok, atom()} | {error, term()}.

Read cookie from ~/.erlang.cookie file.

# resolve_cookie()

    -spec resolve_cookie() -> {ok, atom()} | {error, not_found}.

Resolve the cookie from various sources.

# set_cookie(Cookie)

    -spec set_cookie(atom() | binary()) -> ok.

Set the Erlang cookie for this node and persist it.

Sets the cookie for the current node and attempts to persist it to ~/.erlang.cookie for future sessions.

Examples:

      ok = macula_cluster:set_cookie(my_secret_cookie).
      ok = macula_cluster:set_cookie(&lt;&lt;"my_secret_cookie"&gt;&gt;).

# start_cluster()

    -spec start_cluster() -> ok | {error, term()}.

Start automatic cluster formation with default options.

Uses the static strategy by default, reading nodes from: 1. Application env: `{macula, [{cluster_nodes, [Node1, Node2, ...]}]}` 2. Environment variable: `CLUSTER_NODES` (comma-separated)

If no nodes are configured, starts the DHT-based discovery strategy.

Examples:

      %% With CLUSTER_NODES env var set
      ok = macula_cluster:start_cluster().

      %% Or configure in sys.config
      {macula, [{cluster_nodes, ['node1@host1', 'node2@host2']}]}

# start_cluster(Opts)

    -spec start_cluster(map()) -> ok | {error, term()}.

Start automatic cluster formation with options.

Options: - strategy: `gossip` (default), `static`, `mdns`, `dht`, or `auto` - nodes: List of node atoms (for static strategy) - reconnect_interval: Milliseconds between reconnect attempts (default 5000) - callback: PID or {Module, Function} to receive cluster events

Gossip options (for gossip strategy): - multicast_addr: IPv4 multicast address (default {230, 1, 1, 251}) - port: UDP port (default 45892) - broadcast_interval: Milliseconds between broadcasts (default 1500) - multicast_ttl: TTL for multicast packets (default 1 = same subnet) - secret: Optional binary secret for HMAC authentication

Strategy selection: - `gossip`: UDP multicast gossip for zero-config LAN (like libcluster Gossip) - `static`: Uses a known list of nodes (like libcluster Epmd strategy) - `mdns`: Uses mDNS for local network discovery - `dht`: Uses Macula's DHT for internet-scale discovery - `auto`: Chooses strategy based on configuration

Examples:

      %% Gossip strategy for zero-config LAN discovery (recommended)
      ok = macula_cluster:start_cluster(#{
          strategy => gossip
      }).

      %% Gossip with custom multicast group
      ok = macula_cluster:start_cluster(#{
          strategy => gossip,
          multicast_addr => {239, 1, 1, 1},
          port => 9999,
          secret => &lt;&lt;"my-cluster-secret"&gt;&gt;
      }).

      %% Static strategy with explicit nodes
      ok = macula_cluster:start_cluster(#{
          strategy => static,
          nodes => ['node1@host1', 'node2@host2']
      }).

      %% mDNS strategy for local network
      ok = macula_cluster:start_cluster(#{
          strategy => mdns
      }).

      %% DHT strategy for internet-scale
      ok = macula_cluster:start_cluster(#{
          strategy => dht
      }).

# stop_cluster()

    -spec stop_cluster() -> ok.

Stop automatic cluster formation.

Stops the cluster strategy process and disconnects from managed nodes.

# unmonitor_nodes()

    -spec unmonitor_nodes() -> ok.

Unsubscribe from node up/down events.

Stops the calling process from receiving nodeup/nodedown messages.