Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

MonoID

nb/monoid.livemd

MonoID

SeqMonoID

t = System.os_time(:nanosecond)
{sec, subsec} = {div(t, 1_000_000_000), rem(t, 1_000_000_000)}
unixts = <>
0b10
<> = <>
<>
defmodule SeqMonoID do
  use GenServer

  @impl true
  def init(:ok) do
    {:ok, {0, 0}}
  end

  def gen_id({now, seq}) do
    {sec, subsec} = {div(now, 1_000_000_000), rem(now, 1_000_000_000)}
    <> = <>
    clock = <>
    entropy = :crypto.strong_rand_bytes(6)
    clock <> entropy
  end

  @impl true
  def handle_call(:gen, _from, {last, seq}) do
    now = System.os_time(:nanosecond)

    case now <= last do
      true -> {:reply, gen_id({now, seq + 1}), {last, seq + 1}}
      false -> {:reply, gen_id({now, 0}), {now, 0}}
    end
  end
end
defmodule MonoID do
  def gen(:raw) do
    now = System.os_time(:nanosecond)
    {sec, subsec} = {div(now, 1_000_000_000), rem(now, 1_000_000_000)}
    <> = <>
    clock = <>
    entropy = :crypto.strong_rand_bytes(7)
    clock <> entropy
  end
end
<> = MonoID.gen(:raw)

Base.encode16(<>) <>
  "-" <>
  Base.encode16(<>) <>
  "-" <>
  Base.encode16(<>) <> "-" <> Base.encode16(<>) <> "f-" <> Base.encode16(<>)