# `NoNoncense.MachineId`
[🔗](https://github.com/juulSme/NoNoncense/blob/v1.3.0/lib/no_noncense/machine_id.ex#L1)

Determine unique machine IDs for nodes, which can be used to guarantee uniqueness in a distributed system.

To determine the unique node ID, you must provide a list of possible node identifiers. The possible identifiers are IP addresses, OTP node identifiers, hostnames and fully-qualified domain names. You should only provide possible identifiers that can't conflict with one another. So if you don't explicitly set OTP node names you should not add the default `:"nonode@nohost"` to your identifier list.

Notes:
- The default `:max_nodes` is 512, producing valid IDs in the range 0..511.
- The `node_list` is treated as a set (an `:ordset`) when matching host identifiers; its ordering does not influence which ID is chosen. What matters is that every node uses the same set of possible identifiers so matches are stable across nodes.

> #### Use the same node list everywhere {: .warning}
>
> Your `node_list` must be the same for every node or the generated machine IDs will not be unique.

You can configure the options in your application environment and just pass them into `id/1`.

After https://github.com/blitzstudios/snowflake

# `host_identifiers`

```elixir
@type host_identifiers() :: [binary() | atom()]
```

# `id_opts`

```elixir
@type id_opts() :: [
  machine_id: non_neg_integer() | nil,
  node_list: host_identifiers(),
  max_nodes: pos_integer()
]
```

# `host_identifiers`

```elixir
@spec host_identifiers() :: host_identifiers()
```

Get a list of all identifiers of the current node. You can use one or more of these values to populate your node list.

## Examples / doctests

    iex> MachineId.host_identifiers()
    [:nonode@nohost, "host.mydomain.com", "10.11.12.13", "myhost", "fe80::1234::abcd"]

# `id!`

```elixir
@spec id!(id_opts()) :: non_neg_integer()
```

Determine the current node's machine ID.

## Examples / doctests

    # provide a list of possible node identifiers
    iex> node_list = [:a, :b, :nonode@nohost, "1.1.1.1"]
    iex> MachineId.id!(node_list: node_list)
    2

    # a statically configured ID will override the node list
    iex> node_list = [:a, :b, :nonode@nohost, "1.1.1.1"]
    iex> MachineId.id!(machine_id: 10, node_list: node_list)
    10

    # the node ID must be within the provided range (default 0-511)
    iex> node_list = [:a, :b, :nonode@nohost, "1.1.1.1"]
    iex> MachineId.id!(max_nodes: 2, node_list: node_list)
    ** (RuntimeError) Node ID 2 out of range 0-1

    # raises when the machine ID could not be determined from the node list
    iex> node_list = ["1.1.1.1"]
    iex> MachineId.id!(node_list: node_list)
    ** (RuntimeError) machine ID could not be determined

---

*Consult [api-reference.md](api-reference.md) for complete listing*
