defmodule Shard.Manager do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def init(_) do
state = %{
shards: %{}
}
{:ok, state}
end
def handle_call({:find, shard_id}, _from, state) do
{:reply, state.shards[shard_id], state}
end
def handle_call(:list, _from, state) do
{:reply, Map.to_list(state.shards), state}
end
def handle_cast({:register, shard_id, pid}, state) do
if Map.has_key?(state.shards, shard_id) do
GenServer.cast(pid, {:redundant, shard_id})
state
else
new_shards = Map.put(state.shards, shard_id, pid)
{:noreply, %{ state | shards: new_shards }}
end
end
def handle_cast({:interested, peer_id, peer_pid, shards}, state) do
shards
|> Enum.filter(&(Map.has_key?(state.shards, &1)))
|> Enum.each(&(GenServer.cast(state.shards[&1], {:interested, peer_id, peer_pid})))
{:noreply, state}
end
def handle_cast({:dispatch, peer_id, peer_pid, shard, msg}, state) do
if Map.has_key?(state.shards, shard) do
GenServer.cast(state.shards[shard], {:msg, peer_id, peer_pid, msg})
end
{:noreply, state}
end
end