Class: Protobuf::Nats::UUIDv7Helper

Inherits:
Object
  • Object
show all
Defined in:
lib/protobuf/nats/uuidv7_helper.rb

Class Method Summary collapse

Class Method Details

.age_in_seconds(uuid, current_time: Time.now) ⇒ Float?

Calculate the age of a UUIDv7 in seconds Returns nil if the UUID cannot be parsed

Parameters:

  • uuid (String)

    A UUIDv7 string

  • current_time (Time) (defaults to: Time.now)

    The time to compare against (defaults to Time.now)

Returns:

  • (Float, nil)

    The age in seconds, or nil if parsing fails



52
53
54
55
56
57
# File 'lib/protobuf/nats/uuidv7_helper.rb', line 52

def self.age_in_seconds(uuid, current_time: Time.now)
  timestamp = extract_timestamp(uuid)
  return nil unless timestamp

  current_time - timestamp
end

.extract_timestamp(uuid) ⇒ Time?

Extract the Unix timestamp (in seconds) from a UUIDv7 string Returns nil if the UUID cannot be parsed

Parameters:

  • uuid (String)

    A UUIDv7 string (e.g., “01234567-89ab-7def-0123-456789abcdef”)

Returns:

  • (Time, nil)

    The timestamp embedded in the UUID, or nil if parsing fails



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/protobuf/nats/uuidv7_helper.rb', line 32

def self.extract_timestamp(uuid)
  return nil unless uuid.is_a?(String)

  # UUIDv7 format: first 48 bits (12 hex chars) are Unix timestamp in milliseconds
  # Remove dashes and extract the timestamp portion
  uuid_bytes = uuid.gsub('-', '')
  return nil if uuid_bytes.length < 12

  timestamp_ms = uuid_bytes[0...12].to_i(16)
  Time.at(timestamp_ms / 1000.0)
rescue => e
  nil
end

.generateString

Generate a UUIDv7 string without a CSPRNG. Callers that only need a 48-bit millisecond timestamp prefix (so #age_in_seconds can report a value) plus enough randomness to stay unique among concurrent generators don’t need SecureRandom: its gen_random call dominated per-request CPU and garbage (measured ~6.8us/op and 4 GC-triggering allocations). A per-thread non-cryptographic Random halves both. The layout still matches RFC 9562 UUIDv7 (version 7 + RFC 4122 variant bits).

Returns:

  • (String)

    a UUIDv7 string (e.g. “01234567-89ab-7def-8123-456789abcdef”)



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/protobuf/nats/uuidv7_helper.rb', line 13

def self.generate
  unix_ts_ms = ::Process.clock_gettime(::Process::CLOCK_REALTIME, :millisecond) & 0xffffffffffff
  rng = (::Thread.current[:pb_nats_uuid_rng] ||= ::Random.new)
  format(
    "%08x-%04x-%04x-%04x-%04x%08x",
    (unix_ts_ms >> 16) & 0xffffffff,   # 32 high bits of the ms timestamp
    unix_ts_ms & 0xffff,               # 16 low bits of the ms timestamp
    (0x7000 | rng.rand(0x1000)),       # version 7 + 12 random bits
    (0x8000 | rng.rand(0x4000)),       # RFC 4122 variant + 14 random bits
    rng.rand(0x10000),                 # 16 random bits
    rng.rand(0x100000000)              # 32 random bits
  )
end