global_group(3)

πŸ“¦
version 29.0.6 Β· 3 versions
, in ubuntu stonking

πŸ’– global_group(3) β€” the Erlang Module Definition, bestie edition πŸ’–

okay so this is global_group(3), and it's literally the module that lets you split a system's nodes into global name registration groups. yes, you read that right. it's giving "divide and conquer" but for node namespaces. let's get into it 🫢


✨ NAME ✨

global_group β€” grouping nodes into global name registration groups. cute, concise, iconic. πŸ’…


🌸 DESCRIPTION 🌸

okay so here's the tea: this module makes it possible to partition the nodes of a system into global groups. every single global group gets its own global namespace, see global.

the main advantage of dividing systems into global groups is that the background load decreases while the number of nodes to be updated is reduced when you're manipulating globally registered names. so basically: less work, fewer nodes touched, slay. ✨

the Kernel configuration parameter global_groups is what defines the global groups:

{global_groups, [GroupTuple :: group_tuple()]}

for the processes and nodes to run smoothly using the global group functionality, the following criteria must be met (no cap, these are requirements, not suggestions):

  • An instance of the global group server, global_group, must be running on each node. The processes are automatically started and synchronized when a node is started.
  • All involved nodes must agree on the global group definition, otherwise the behavior of the system is undefined. (πŸ’€ seriously, don't mix and match definitions)
  • All nodes in the system must belong to exactly one global group.

in the following descriptions, a group node is a node belonging to the same global group as the local node. iykyk 🧚

πŸ‘€ Notes πŸ‘€

  • In the situation where a node has lost its connections to other nodes in its global group, but has connections to nodes in other global groups, a request from another global group can produce an incorrect or misleading result. For example, the isolated node can have inaccurate information about registered names in its global group. so like… vibe check your topology first, bestie.
  • Function send/2,3 is not secure. 🚨
  • Distribution of applications is highly dependent of the global group definitions. It is not recommended that an application is distributed over many global groups, as the registered names can be moved to another global group at failover/takeover. Nothing prevents this to be done, but the application code must then handle the situation. (so you can, but it's gonna be a whole thing 😭)

πŸ”— See Also

global, erl


πŸ¦‹ DATA TYPES πŸ¦‹

group_name() :: atom().
group_tuple() ::
          {GroupName :: group_name(), [node()]} |
          {GroupName :: group_name(),
           PublishType :: publish_type(),
           [node()]}.

A GroupTuple without PublishType is the same as a GroupTuple with PublishType equal to normal. (so normal is the lowkey default, periodt)

info_item() ::
          {state, State :: sync_state()} |
          {own_group_name, GroupName :: group_name()} |
          {own_group_nodes, Nodes :: [node()]} |
          {synched_nodes, Nodes :: [node()]} |
          {sync_error, Nodes :: [node()]} |
          {no_contact, Nodes :: [node()]} |
          {other_groups, Groups :: [group_tuple()]} |
          {monitoring, Pids :: [pid()]}.
name() :: atom().

A registered name. ✨

publish_type() :: hidden | normal.

A node started with command-line flag -hidden (see erl) is said to be a hidden node. A hidden node establishes hidden connections to nodes not part of the same global group, but normal (visible) connections to nodes part of the same global group.

A global group defined with PublishType equal to hidden is said to be a hidden global group. All nodes in a hidden global group are hidden nodes, whether they are started with command-line flag -hidden or not. (yes, they're all in on it 🫣)

sync_state() :: no_conf | synced.
where() :: {node, node()} | {group, group_name()}.

πŸ”₯ FUNCTIONS πŸ”₯

  • global_groups() -> {GroupName, GroupNames} | undefined

with:

GroupName :: group_name(),
GroupNames :: [GroupName].

Returns a tuple containing the name of the global group that the local node belongs to, and the list of all other known group names.

Returns undefined if no global groups are defined. πŸ’€

  • info() -> [info_item()].

Returns a list containing information about the global groups. Each list element is a tuple. The order of the tuples is undefined. (so don't you dare assume an order, bestie)

  • {state, State} β€” If the local node is part of a global group, State is equal to synced. If no global groups are defined, State is equal to no_conf.
  • {own_group_name, GroupName} β€” The name (atom) of the group that the local node belongs to.
  • {own_group_nodes, Nodes} β€” A list of node names (atoms), the group nodes.
  • {synced_nodes, Nodes} β€” A list of node names, the group nodes currently synchronized with the local node.
  • {sync_error, Nodes} β€” A list of node names, the group nodes with which the local node has failed to synchronize.
  • {no_contact, Nodes} β€” A list of node names, the group nodes to which there are currently no connections.
  • {other_groups, Groups} β€” Groups is a list of tuples {GroupName, Nodes}, specifying the name and nodes of the other global groups.
  • {monitoring, Pids} β€” A list of pids, specifying the processes that have subscribed to nodeup and nodedown messages.
  • monitor_nodes(Flag) -> ok β€” when Flag :: boolean().

Alter the calling process' subscription of node status change messages. πŸ‘‘

If Flag is equal to true the calling process starts subscribing to node status change messages. If equal to false it stops subscribing.

A process that has subscribed receives the messages {nodeup, Node} and {nodedown, Node} when a group node connects or disconnects, respectively.

  • own_nodes() -> Nodes β€” when Nodes :: [Node :: node()].

Returns the names of all group nodes, regardless of their current status. so even the ones not picking up the phone πŸ“ž

  • registered_names(Where) -> Names

with:

Where :: where(),
Names :: [Name :: name()].

Returns a list of all names that are globally registered on the specified node or in the specified global group.

  • send(Name, Msg) -> pid() | {badarg, {Name, Msg}} β€” when Name :: name(), Msg :: term().

Sends Msg to the pid represented by the globally registered name Name.

send/2 searches for Name any any global group. The global groups are searched in the order that they appear in the value of configuration parameter global_groups. 🎯

If Name is found, message Msg is sent to the corresponding pid. The pid is also the return value of the function. If the name is not found, the function returns {badarg, {Name, Msg}}.

  • send(Where, Name, Msg) -> pid() | {badarg, {Name, Msg}} β€” when Where :: where(), Name :: name(), Msg :: term().

Equivalent to send(Name, Msg) except that he search is limited to the node or global group specified by Where.

  • sync() -> ok.

Synchronizes the group nodes, that is, the global name servers on the group nodes. Also checks the names globally registered in the current global group and unregisters them on any known node not part of the group.

If synchronization is not possible, an error report is sent to the error logger (see also error_logger. 😭

Returns {error, {'invalid global_groups definition', Bad}} if configuration parameter global_groups has an invalid value Bad.

  • whereis_name(Name) -> pid() | undefined β€” when Name :: name().

Searched for Name in any global group. πŸ•΅οΈ

The global groups are searched in the order that they appear in the value of configuration parameter global_groups.

If Name is found, the corresponding pid is returned. If the name is not found, the function returns undefined.

  • whereis_name(Where, Name) -> pid() | undefined β€” when Where :: where(), Name :: name().

Equivalent to whereis_name(Name) except that he search is limited to the node or global group specified by Where.


πŸ’– ok bestie reminder: send/2,3 is not secure. send/2,3 is not secure. i'm saying it twice because you WILL forget. also, if all involved nodes don't agree on the global group definition, the behavior of the system is undefined β€” that's the scary kind of undefined, not the fun kind.

and that's the whole thing! you ate this. πŸ“

Ericsson AB Β· kernel 11.0.3 Β· mwah, go sync some nodes πŸ’…βœ¨πŸŒˆ

πŸ“¦ where this page comes from