Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ use Mix.Config

config :snowflake,
nodes: ["127.0.0.1"],
epoch: 1473562509301
epoch: 1_473_562_509_301
5 changes: 3 additions & 2 deletions lib/snowflake.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ defmodule Snowflake do
Generates a snowflake ID, each call is guaranteed to return a different ID
that is sequantially larger than the previous ID.
"""
@spec next_id() :: {:ok, integer} |
{:error, :backwards_clock}
@spec next_id() ::
{:ok, integer}
| {:error, :backwards_clock}
def next_id() do
GenServer.call(Snowflake.Generator, :next_id)
end
Expand Down
12 changes: 8 additions & 4 deletions lib/snowflake/generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ defmodule Snowflake.Generator do
{:error, :seq_overflow} ->
:timer.sleep(1)
handle_call(:next_id, from, state)

{:error, :backwards_clock} ->
{:reply, {:error, :backwards_clock}, state}

{:ok, new_ts, new_seq} ->
new_state = {epoch, new_ts, machine_id, new_seq}
{:reply, {:ok, create_id(new_ts, machine_id, new_seq)}, new_state}
Expand All @@ -42,6 +44,7 @@ defmodule Snowflake.Generator do
@seq_overflow -> {:error, :seq_overflow}
next_seq -> {:ok, prev_ts, next_seq}
end

new_ts ->
cond do
new_ts < prev_ts -> {:error, :backwards_clock}
Expand All @@ -51,10 +54,11 @@ defmodule Snowflake.Generator do
end

defp create_id(ts, machine_id, seq) do
<< new_id :: unsigned-integer-size(64)>> = <<
ts :: unsigned-integer-size(42),
machine_id :: unsigned-integer-size(10),
seq :: unsigned-integer-size(12) >>
<<new_id::unsigned-integer-size(64)>> = <<
ts::unsigned-integer-size(42),
machine_id::unsigned-integer-size(10),
seq::unsigned-integer-size(12)
>>

new_id
end
Expand Down
14 changes: 9 additions & 5 deletions lib/snowflake/helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ defmodule Snowflake.Helper do
defp machine_id(_id), do: machine_id(nil)

defp ip_addrs() do
case :inet.getifaddrs do
case :inet.getifaddrs() do
{:ok, ifaddrs} ->
ifaddrs
|> Enum.flat_map(fn {_, kwlist} ->
Expand All @@ -49,11 +49,15 @@ defmodule Snowflake.Helper do
|> Enum.filter(&(tuple_size(elem(&1, 1)) in [4, 6]))
|> Enum.map(fn {_, addr} ->
case addr do
{a, b, c, d} -> [a, b, c, d] |> Enum.join(".") # ipv4
{a, b, c, d, e, f} -> [a, b, c, d, e, f] |> Enum.join(":") # ipv6
# ipv4
{a, b, c, d} -> [a, b, c, d] |> Enum.join(".")
# ipv6
{a, b, c, d, e, f} -> [a, b, c, d, e, f] |> Enum.join(":")
end
end)
_ -> []

_ ->
[]
end
end

Expand All @@ -63,7 +67,7 @@ defmodule Snowflake.Helper do
end

defp fqdn() do
case :inet.get_rc[:domain] do
case :inet.get_rc()[:domain] do
nil -> nil
domain -> hostname() <> "." <> to_string(domain)
end
Expand Down
14 changes: 8 additions & 6 deletions lib/snowflake/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ defmodule Snowflake.Util do
@spec first_snowflake_for_timestamp(integer) :: integer
def first_snowflake_for_timestamp(timestamp) do
ts = timestamp - Snowflake.Helper.epoch()

<< new_id :: unsigned-integer-size(64)>> = <<
ts :: unsigned-integer-size(42),
0 :: unsigned-integer-size(10),
0 :: unsigned-integer-size(12) >>

<<new_id::unsigned-integer-size(64)>> = <<
ts::unsigned-integer-size(42),
0::unsigned-integer-size(10),
0::unsigned-integer-size(12)
>>

new_id
end
Expand Down Expand Up @@ -61,7 +62,8 @@ defmodule Snowflake.Util do
defp bucket_size(unit_type, units) do
case unit_type do
:hours -> 1000 * 60 * 60 * units
_ -> 1000 * 60 * 60 * 24 * units # days is default
# days is default
_ -> 1000 * 60 * 60 * 24 * units
end
end
end
7 changes: 3 additions & 4 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ defmodule Snowflake.Mixfile do
app: :snowflake,
version: @version,
source_url: @url,
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
maintainers: @maintainers,
description: "Elixir Snowflake ID Generator",
elixir: "~> 1.3",
Expand All @@ -24,8 +24,7 @@ defmodule Snowflake.Mixfile do
end

def application do
[applications: [],
mod: {Snowflake, []}]
[applications: [], mod: {Snowflake, []}]
end

defp deps do
Expand Down