aboutsummaryrefslogtreecommitdiff
path: root/lib/manager.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/manager.ex')
-rw-r--r--lib/manager.ex46
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