Skip to content
Merged
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
12 changes: 6 additions & 6 deletions lib/cachex/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ defmodule Cachex.Router do

Please see all child implementations for supported options.
"""
@callback init(cache :: Cachex.t(), options :: Keyword.t()) :: any
@callback init(cache :: Cachex.t(), options :: Keyword.t()) :: any()

@doc """
Retrieve the list of nodes from a routing state.
"""
@callback nodes(state :: any) :: [atom]
@callback nodes(state :: any()) :: [atom()]

@doc """
Route a key to a node in a routing state.
"""
@callback route(state :: any, key :: any) :: atom
@callback route(state :: any(), key :: any()) :: atom()

@doc """
Create a child specification to back a routing state.
Expand Down Expand Up @@ -74,22 +74,22 @@ defmodule Cachex.Router do
@doc """
Retrieve all currently connected nodes (including this one).
"""
@spec connected() :: [atom]
@spec connected() :: [atom()]
def connected(),
do: [node() | :erlang.nodes(:connected)]

@doc """
Retrieve all routable nodes for a cache.
"""
@spec nodes(cache :: Cachex.t()) :: {:ok, [atom]}
@spec nodes(cache :: Cachex.t()) :: {:ok, [atom()]}
def nodes(cache(router: router(module: module, state: state))),
do: {:ok, module.nodes(state)}

@doc """
Executes a previously dispatched action..
"""
# The first match short circuits local-only caches
@spec route(Cachex.t(), atom, {atom, [any]}) :: any
@spec route(Cachex.t(), atom(), {atom(), [any()]}) :: any()
def route(cache(router: router(module: Router.Local)) = cache, module, call),
do: route_local(cache, module, call)

Expand Down
6 changes: 3 additions & 3 deletions lib/cachex/router/jump.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Cachex.Router.Jump do
by using `Node.self/0` and `Node.list/1`.

"""
@spec init(cache :: Cachex.t(), options :: Keyword.t()) :: [atom]
@spec init(cache :: Cachex.t(), options :: Keyword.t()) :: [atom()]
def init(_cache, options) do
options
|> Keyword.get_lazy(:nodes, &Router.connected/0)
Expand All @@ -40,14 +40,14 @@ defmodule Cachex.Router.Jump do
@doc """
Retrieve the list of nodes from a jump hash routing state.
"""
@spec nodes(nodes :: [atom]) :: [atom]
@spec nodes(nodes :: [atom()]) :: [atom()]
def nodes(nodes),
do: nodes

@doc """
Route a key to a node in a jump hash routing state.
"""
@spec route(nodes :: [atom], key :: any) :: atom
@spec route(nodes :: [atom()], key :: any) :: atom()
def route(nodes, key) do
slot =
key
Expand Down
4 changes: 2 additions & 2 deletions lib/cachex/router/local.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ defmodule Cachex.Router.Local do
@doc """
Retrieve the list of nodes from a local routing state.
"""
@spec nodes(state :: nil) :: [atom]
@spec nodes(state :: nil) :: [atom()]
def nodes(_state),
do: [node()]

@doc """
Route a key to a node in a local routing state.
"""
@spec route(state :: nil, key :: any) :: atom
@spec route(state :: nil, key :: any()) :: atom()
def route(_state, _key),
do: node()
end
6 changes: 3 additions & 3 deletions lib/cachex/router/mod.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ defmodule Cachex.Router.Mod do
by using `Node.self/0` and `Node.list/1`.

"""
@spec init(cache :: Cachex.t(), options :: Keyword.t()) :: [atom]
@spec init(cache :: Cachex.t(), options :: Keyword.t()) :: [atom()]
def init(_cache, options) do
options
|> Keyword.get_lazy(:nodes, &Router.connected/0)
Expand All @@ -37,14 +37,14 @@ defmodule Cachex.Router.Mod do
@doc """
Retrieve the list of nodes from a modulo routing state.
"""
@spec nodes(nodes :: [atom]) :: [atom]
@spec nodes(nodes :: [atom()]) :: [atom()]
def nodes(nodes),
do: Enum.sort(nodes)

@doc """
Route a key to a node in a modulo routing state.
"""
@spec route(nodes :: [atom], key :: any) :: atom
@spec route(nodes :: [atom()], key :: any()) :: atom()
def route(nodes, key) do
slot =
key
Expand Down
10 changes: 8 additions & 2 deletions lib/cachex/router/ring.ex
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ defmodule Cachex.Router.Ring do
@doc """
Retrieve the list of nodes from a ring routing state.
"""
@spec nodes(ring :: Ring.t()) :: {:ok, [atom]}
@spec nodes(ring :: Ring.t()) :: {:ok, [atom()]}
def nodes(ring) do
with {:ok, nodes} <- Ring.get_nodes(ring) do
nodes
Expand All @@ -76,8 +76,14 @@ defmodule Cachex.Router.Ring do
@doc """
Route a key to a node in a ring routing state.
"""
@spec route(ring :: Ring.t(), key :: any) :: {:ok, atom}
@spec route(ring :: Ring.t(), key :: any()) :: {:ok, atom()}
def route(ring, key) do
key =
case String.Chars.impl_for(key) do
nil -> :erlang.term_to_binary(key)
_na -> key
end

with {:ok, node} <- Ring.find_node(ring, key) do
node
end
Expand Down
19 changes: 19 additions & 0 deletions test/cachex/router/ring_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ defmodule Cachex.Router.RingTest do
assert Cachex.Router.Ring.route(state, "erlang") in nodes
end

test "routing keys via a ring router with no protocol" do
# create a test cache cluster for nodes
{cache, nodes, _cluster} =
TestUtils.create_cache_cluster(3,
router: Cachex.Router.Ring
)

# convert the name to a cache and sort
cache = Services.Overseer.lookup(cache)

# fetch the router state after initialize
cache(router: router(state: state)) = cache

# test that we can route to expected nodes
assert Cachex.Router.nodes(cache) == {:ok, nodes}
assert Cachex.Router.Ring.route(state, {"elixir"}) in nodes
assert Cachex.Router.Ring.route(state, {"erlang"}) in nodes
end

test "routing keys via a ring router with defined nodes" do
# create a test cache cluster for nodes
{cache, _nodes, _cluster} =
Expand Down