5 ms·
Erlang/Elixir (BEAM VM) makes this very clear - it's a distinction between monotonic vs strictly monotonic. https://www.erlang.org/doc/apps/erts/time_correctio
by rdtsc 3y ago
Erlang/Elixir (BEAM VM) makes this very clear - it's a distinction between monotonic vs strictly monotonic.
https://www.erlang.org/doc/apps/erts/time_correction.html#monotonically-increasing https://www.erlang.org/doc/apps/erts/time_correction.html#mo...
> In a monotonically increasing sequence of values, all values that have a predecessor are either larger than or equal to its predecessor.
These are available via the https://www.erlang.org/doc/man/erlang.html#monotonic_time-0 https://www.erlang.org/doc/man/erlang.html#monotonic_time-0 function.
https://www.erlang.org/doc/apps/erts/time_correction.html#strictly-monotonically-increasing https://www.erlang.org/doc/apps/erts/time_correction.html#st...
> In a strictly monotonically increasing sequence of values, all values that have a predecessor are larger than its predecessor.
Strictly monotonic values imply some synchronization / coordination, with an associated performance impact when there are many concurrent processes. This functionality is available via the https://www.erlang.org/doc/man/erlang.html#unique_integer-1 https://www.erlang.org/doc/man/erlang.html#unique_integer-1 function. With a warning associated with it:
> Strictly monotonically increasing values are inherently quite expensive to generate and scales poorly. This is because the values need to be synchronized between CPU cores. That is, do not pass the monotonic modifier unless you really need strictly monotonically increasing values.
- derefr 3y agoRelatedly, Erlang's own refs aren't created by a strictly-monotonic global generator; but rather are internally a pair of a regular monotonic identifier, and the PID of the requesting process. In other words, they're akin to UUIDv1s, or to https://en.wikipedia.org/wiki/Snowflake_ID https://en.wikipedia.org/wiki/Snowflake_ID s. You only really need strictly monotonic global identifiers if you need immediately-consistent first/last-write-wins. If you can instead rely on eventually-consistent first/last-write-wins (i.e. if your write events enter an event store/queue that linearizes them by ID, and then all "simultaneous" writes but the one with highest ID priority can be dropped/ignored, either during processing, or on read), then I'd recommend first considering packed (nodeID, seq) pairs. And, if you want global event orderibility, considering the snowflake ID formulation (timestampMajor, nodeID, timestampMinor, seq) specifically.