diff options
Diffstat (limited to 'lib/manager.ex')
-rw-r--r-- | lib/manager.ex | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/manager.ex b/lib/manager.ex new file mode 100644 index 0000000..ce11117 --- /dev/null +++ b/lib/manager.ex @@ -0,0 +1,46 @@ +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 |