# global_group

### MODULE

global_group

### MODULE SUMMARY

Grouping Nodes to Global Name Registration Groups

### DESCRIPTION

The global group function makes it possible to group the nodes in a system into partitions, each partition having its own global name space, refer to `global(3)`. These partitions are called global groups.
The main advantage of dividing systems to global groups is that the background load decreases while the number of nodes to be updated is reduced when manipulating globally registered names.

The `global_groups`-key in the `.config` file defines the global groups:

`{global_groups, [GroupTuple]}`

Types:

- `GroupTuple = {GroupName, [Node]} | {GroupName, PublishType, [Node]}`
- `GroupName = atom()` (naming a global group)
- `PublishType = normal | hidden`
- `Node = atom()` (naming a node)

A `GroupTuple` without `PublishType` is the same as a `GroupTuple` with `PublishType` equal to `normal`.

The command `erl -config File` starts a node with a configuration file named `File.config`. If the `global_groups`-key is not defined the system will start as a whole, without any partitions. When the key is not defined, the services of this function will not give any extra value to `global(3)`.

A hidden node will establish hidden connections to nodes not part of the same global group, and normal (visible) connections to nodes part of the same global group. Hidden connections aren't published on neither of the connected nodes, i.e. neither of the connected nodes are part of the result from `nodes/0` on the other node.

In a hidden global group (a global group defined with `PublishType` equal to `hidden`) all nodes are hidden nodes.

Hidden nodes can also be part of normal global groups. Nodes started with the `-hidden` switch will be hidden nodes even if they are part of a normal group, see erl(1). Other nodes in the group will not be affected by this.

For the processes and nodes to run smoothly using this function the following criteria must be met:

- The global group function must have a server process, `global_group`, running on each node.
  NOTE: The processes are automatically started and synchronized when a node is started.
- All processes must agree with the group definition in the immediate global group. If two nodes do not agree, these nodes will not synchronize their name space and an error message will be logged in the error logger.
  Example: If one node has an illegal global group definition, such a node will run isolated from the other nodes regarding the global name space; but not regarding other system functions, e.g distribution of applications, refer to chapter `NOTE` below.
- Nodes can only belong to one global group.

When the global group definitions are to be changed in a system upgrade, the upgrade must fulfill the following steps:

1. First, all nodes which are to be removed from a global group must be taken down.
2. Nodes which are not affected by the redefinition of the global groups are to be upgraded to be aware of the new global group definitions.
   NOTE: All nodes in the system, also nodes in unchanged global groups, must be upgraded. This because e.g `send` must have an accurate view of the total system.
3. Finally, all nodes which are new to a global group can be started.

When a non partitioned system is to be upgraded to become a partitioned system, all nodes belonging to a global group will be disconnected from all nodes not belonging to its immediate global group.

### EXPORTS

`global_groups() -> {OwnGroupName, [OtherGroupName]} | undefined`

Types:

`OwnGroupName = atom()`
`OtherGroupName = atom()`
`ErrorMsg = term()`

Returns the names of all the global groups known to the immediate global group.

`info() -> [{state, State}, {own_group_name, atom()}, {own_group_nodes, [Node]}, {synced_nodes, [Node]}, {sync_error, [Node]}, {no_contact, [Node]}, {other_groups, Other_grps}, {monitoring, [pid()]}]`

Types:

`State = no_conf | synced`
`Other_grps = [{OtherGrpName, [Node]}]`
`OtherGrpName = atom()`
`Node = atom()`

Returns the state of the global group process. In the following 'nodes' refers to nodes in the immediate global group. `synced_nodes` lists the nodes this node is synchronized with at this moment. `` lists the nodes defining the own global group. `sync_error` lists the nodes with this node could not be synchronize. `no_contact` lists nodes with this node do not yet have established contact. `other_groups` shows the definition of the other global groups in the system. `monitoring` lists the processes which have subscribed on `nodeup` and `nodedown` messages.

`monitor_nodes(Flag) -> ok`

Types:

`Flag = bool()`

The requesting process receives `{nodeup,Node}` and `{nodedown,Node}` messages about the nodes from the immediate global group. If the flag `Flag` is set to `true` the service is turned on; `false` turns it off.

`own_nodes() -> [Node] | {error, ErrorMsg}`

Types:

`Node = atom()`
`ErrorMsg = term()`

Returns the names of all nodes from the immediate global group, despite of the status of the nodes. Use `info/0` to get the information of the current status of the nodes.

`registered_names({node, Node}) -> [Name] | {error, ErrorMsg}`
`registered_names({group, GlobalGroupName}) -> [Name]`

Types:

`Name = term()`
`Node = atom()`
`GlobalGroupName = atom()`
`ErrorMsg = term()`

Returns a lists of all globally registered names on the specified node or from the specified global group.

`send(Name, Msg) -> Pid | {badarg, Msg} | {error, ErrorMsg}`
`send({node, Node}, Name, Msg) -> Pid | {badarg, Msg} | {error, ErrorMsg}`
`send({group, GlobalGroupName}, Name, Msg) -> Pid | {badarg, Msg} | {error, ErrorMsg}`

Types:

`GlobalGroupName = atom()`
`Msg = term()`
`Name = term()`
`Node = atom()`
`Pid = pid()`
`ErrorMsg = term()`

`send/2` searches for the registered `Name` in all global groups defined, in the order of appearance in the `.config`-file, until the registered name is found or all groups are searched. If `Name` is found, the message `Msg` is sent to it. If it is not found, the function exits with reason `{badarg, {Name, Msg}}`.

`send/3` searches for the registered `Name` in either the specified node or the specified global group. If the registered name is found, the message `Msg` is sent to that process. If `Name` is not found, the function exits with reason `{badarg, {Name, Msg}}`.

`sync() -> ok`

`sync` synchronizes the global name servers on the nodes in the immediate global group. It also unregisters the names registered in the immediate global group on known nodes outside to the immediate global group.

If it the `global_groups` definition is unvalid, the function exits with reason `{error, {'invalid global_groups definition', NodeGrpDef}}`.

`whereis_name(Name) -> Pid | undefined | {error, ErrorMsg}`
`whereis_name({node, Node}, Name) -> Pid | undefined | {error, ErrorMsg}`
`whereis_name({group, GlobalGroupName}, Name) -> Pid | undefined | {error, ErrorMsg}`

Types:

`GlobalGroupName = atom()`
`Name = term()`
`Node = atom()`
`Pid = pid()`

`whereis_name/1` searches for the registered `Name` in all global groups defined, in the order of appearance in the `.config`-file, until the registered name is found or all groups are searched.

`whereis_name/2` searches for the registered `Name` in either the specified node or the specified global group.

Returns either the atom `undefined`, or the Pid which is associated with `Name`.

`start()`
`start_link() -> {ok, Pid} | {error, Reason}`

This function starts the global group server. Normally, the server is started automatically.

`stop() -> void()`

Stop the global group server.

### NOTE

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 the other global group may produce an incorrect or misleading result. When this occurs the isolated node may not have accurate information, for example, about registered names in its global group.

Note also that the send function is not secure.

Distribution of applications is highly dependent of the global group definitions. It is not recommended that an application is distributed over several global groups of the obvious reason that the registered names may be moved to another global group at failover/takeover. There is nothing preventing doing this, but the application code must in such case handle the situation.

### SEE ALSO

erl(1), global(3)

### AUTHORS

Esko Vierumäki - support@erlang.ericsson.se
Rickard Green - support@erlang.ericsson.se

kernel 2.9
Copyright © 1991-2003 Ericsson Utvecklings AB