Current section

Files

Jump to
snakepit lib snakepit run_id.ex
Raw

lib/snakepit/run_id.ex

defmodule Snakepit.RunID do
@moduledoc """
Generates short, unique BEAM run identifiers.
Format: 7 characters, base36-encoded
Components: timestamp (5 chars) + counter (2 chars)
Example: "k3x9a2p"
These IDs are embedded in Python process command lines for reliable
identification and cleanup across BEAM restarts.
"""
@doc """
Generates a unique 7-character run ID.
## Examples
iex> run_id = Snakepit.RunID.generate()
iex> String.length(run_id)
7
"""
def generate do
# Use last 5 digits of *second* timestamp (base36)
# Cycles every ~60 million seconds (~2 years)
timestamp = System.system_time(:second)
time_component = timestamp |> rem(60_466_176) |> Integer.to_string(36) |> String.downcase()
time_part = String.pad_leading(time_component, 5, "0")
# Add 2 counter characters for collision resistance within the same second
counter_part =
System.unique_integer([:positive, :monotonic])
|> rem(1296)
|> Integer.to_string(36)
|> String.downcase()
|> String.pad_leading(2, "0")
time_part <> counter_part
end
@doc """
Extracts run ID from a process command line.
Supports both --snakepit-run-id and --run-id formats.
## Examples
iex> cmd = "python3 grpc_server.py --snakepit-run-id k3x9a2p --port 50051"
iex> Snakepit.RunID.extract_from_command(cmd)
{:ok, "k3x9a2p"}
iex> Snakepit.RunID.extract_from_command("no run id here")
{:error, :not_found}
"""
def extract_from_command(command) when is_binary(command) do
# Try new format first (--run-id)
case Regex.run(~r/--run-id\s+([0-9a-z]{7})/, command) do
[_, run_id] ->
{:ok, run_id}
nil ->
# Try old format (--snakepit-run-id) with 7-char short IDs
case Regex.run(~r/--snakepit-run-id\s+([0-9a-z]{7})/, command) do
[_, run_id] -> {:ok, run_id}
nil -> {:error, :not_found}
end
end
end
def extract_from_command(_), do: {:error, :not_found}
end