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