Jido.Signal.ID (Jido Signal v1.0.0)
View SourceManages UUID7-based signal IDs for the bus system. Provides utilities for generating, comparing, and extracting information from signal IDs.
UUID7s provide several benefits for signal IDs:
- Monotonically increasing (timestamp-based)
- Contain embedded timestamps and sequence numbers
- High uniqueness guarantees within the same millisecond
- Good sequential scanning performance
UUID7 Format:
- First 48 bits: Unix timestamp in milliseconds
- Next 12 bits: Sequence number (monotonic counter within each millisecond)
- Remaining bits: Random data
This ensures that:
- IDs are globally ordered by timestamp
- IDs generated in the same millisecond are ordered by sequence number
- IDs with same timestamp and sequence are ordered lexicographically
Usage Examples
# Generate UUID7
{id, timestamp} = Jido.Signal.ID.generate()
# Compare IDs chronologically
:lt = Jido.Signal.ID.compare(older_id, newer_id)
# Extract components
timestamp = Jido.Signal.ID.extract_timestamp(id)
sequence = Jido.Signal.ID.sequence_number(id)
Summary
Functions
Compares two UUID7s chronologically.
Returns :lt
, :eq
, or :gt
based on the following order
Extracts the Unix timestamp (in milliseconds) from a UUID7 string. UUID7 embeds a 48-bit timestamp in its first 6 bytes.
Formats a timestamp and sequence as a sortable string. Useful for version strings or ordering.
Generates a new signal ID using UUID7.
Generates a new signal ID using UUID7, returning just the UUID string.
Generates multiple sequential UUIDs in a batch. All UUIDs will be strictly ordered and unique within the same millisecond. If the batch size would exceed the available sequence numbers (4096), it will use multiple milliseconds.
Generates a UUID7 with a specific timestamp and sequence number. This ensures strict ordering of IDs within the same millisecond.
Returns the sequence number portion of the UUID7. This is a 12-bit monotonic counter within each millisecond.
Validates that a string is a valid UUID7. Returns true if the input is a valid UUID7 string, false otherwise.
Types
@type comparison_result() :: :lt | :eq | :gt
@type timestamp() :: non_neg_integer()
@type uuid7() :: String.t()
Functions
@spec compare(uuid7(), uuid7()) :: comparison_result()
Compares two UUID7s chronologically.
Returns :lt
, :eq
, or :gt
based on the following order:
- Timestamp comparison
- If timestamps match, sequence number comparison
- If both match, lexicographical comparison of remaining bits
Examples
Jido.Signal.ID.compare(older_id, newer_id)
#=> :lt
Jido.Signal.ID.compare(newer_id, older_id)
#=> :gt
Jido.Signal.ID.compare(id, id)
#=> :eq
Extracts the Unix timestamp (in milliseconds) from a UUID7 string. UUID7 embeds a 48-bit timestamp in its first 6 bytes.
Examples
ts = Jido.Signal.ID.extract_timestamp("018df6f0-1234-7890-abcd-ef0123456789")
#=> 1677721600000
Formats a timestamp and sequence as a sortable string. Useful for version strings or ordering.
Returns a string in the format "timestamp-sequence".
Examples
Jido.Signal.ID.format_sortable("018df6f0-1234-7890-abcd-ef0123456789")
#=> "1677721600000-42"
Generates a new signal ID using UUID7.
Returns a tuple containing the generated ID and its embedded timestamp. The timestamp is in Unix milliseconds.
Examples
{id, ts} = Jido.Signal.ID.generate()
#=> {"018df6f0-1234-7890-abcd-ef0123456789", 1677721600000}
@spec generate!() :: uuid7()
Generates a new signal ID using UUID7, returning just the UUID string.
Examples
id = Jido.Signal.ID.generate!()
#=> "018df6f0-1234-7890-abcd-ef0123456789"
@spec generate_batch(pos_integer()) :: {[uuid7()], timestamp()}
Generates multiple sequential UUIDs in a batch. All UUIDs will be strictly ordered and unique within the same millisecond. If the batch size would exceed the available sequence numbers (4096), it will use multiple milliseconds.
Examples
{ids, timestamp} = Jido.Signal.ID.generate_batch(5)
#=> {["018df6f0-0001-...", "018df6f0-0002-..."], 1677721600000}
# Verify ordering
[id1, id2 | _] = ids
:lt = Jido.Signal.ID.compare(id1, id2)
@spec generate_sequential(timestamp(), non_neg_integer()) :: uuid7()
Generates a UUID7 with a specific timestamp and sequence number. This ensures strict ordering of IDs within the same millisecond.
Parameters
- timestamp - Unix timestamp in milliseconds
- sequence - A number between 0 and 4095 (12 bits)
Examples
id = Jido.Signal.ID.generate_sequential(timestamp, 1)
#=> "018df6f0-0001-7890-abcd-ef0123456789"
@spec sequence_number(uuid7()) :: non_neg_integer()
Returns the sequence number portion of the UUID7. This is a 12-bit monotonic counter within each millisecond.
Examples
seq = Jido.Signal.ID.sequence_number("018df6f0-1234-7890-abcd-ef0123456789")
#=> 42
Validates that a string is a valid UUID7. Returns true if the input is a valid UUID7 string, false otherwise.
Examples
Jido.Signal.ID.valid?("018df6f0-1234-7890-abcd-ef0123456789")
#=> true
Jido.Signal.ID.valid?("not-a-uuid")
#=> false