Snowflakex (Snowflakex v1.2.0)

Copy Markdown View Source

Generates unique, roughly time-ordered 64-bit ID numbers ("snowflakes") without coordination between nodes.

Snowflakex is modeled after Twitter's Snowflake. Every ID is a positive integer composed of (from most to least significant bit):

  • 1 unused sign bit, always 0
  • 41 bits timestamp in milliseconds since the Snowflakex epoch (2016-12-05T08:51:41.749Z), which lasts for about 69 years
  • 10 bits machine id, allowing up to 1024 generating nodes
  • 12 bits sequence number, allowing up to 4096 IDs per millisecond and node

Configuration

Every node generating IDs needs a machine id between 0 and 1023 that is unique among all nodes:

config :snowflakex, machine_id: 123

The application refuses to start without a valid machine id.

Usage

iex> {:ok, id} = Snowflakex.new()
iex> is_integer(id)
true

Summary

Types

The components of a snowflake, as returned by decompose/1.

t()

A snowflake ID, a non-negative integer of at most 63 bits.

Functions

Splits a snowflake into its components.

Returns the Snowflakex epoch in milliseconds since the Unix epoch.

Returns the highest machine id that can be configured.

Obtains a new snowflake.

Obtains a new snowflake.

Types

components()

@type components() :: %{timestamp: integer(), machine_id: 0..1023, sequence: 0..4095}

The components of a snowflake, as returned by decompose/1.

t()

@type t() :: non_neg_integer()

A snowflake ID, a non-negative integer of at most 63 bits.

Functions

decompose(snowflake)

@spec decompose(t()) :: components()

Splits a snowflake into its components.

The :timestamp is given in milliseconds since the Unix epoch and can be converted with DateTime.from_unix!(timestamp, :millisecond).

Examples

iex> Snowflakex.decompose(4_194_476_039)
%{timestamp: 1_480_927_902_749, machine_id: 42, sequence: 7}

iex> id = Snowflakex.new!()
iex> %{machine_id: 42} = Snowflakex.decompose(id)

epoch()

@spec epoch() :: pos_integer()

Returns the Snowflakex epoch in milliseconds since the Unix epoch.

Examples

iex> Snowflakex.epoch() |> DateTime.from_unix!(:millisecond)
~U[2016-12-05 08:51:41.749Z]

max_machine_id()

@spec max_machine_id() :: pos_integer()

Returns the highest machine id that can be configured.

new()

@spec new() :: {:ok, t()} | {:error, String.t()}

Obtains a new snowflake.

Returns {:ok, snowflake} or {:error, message}, the latter only when the system clock moved backwards since the last ID was generated.

Examples

iex> {:ok, id} = Snowflakex.new()
iex> id > 0
true

new!()

@spec new!() :: t()

Obtains a new snowflake.

Raises Snowflakex.ClockError when the system clock moved backwards since the last ID was generated.

Examples

iex> id = Snowflakex.new!()
iex> id > 0
true