aboutsummaryrefslogtreecommitdiff
path: root/lib/manager.ex
blob: ce11117b460a717c7cc63622d6240c04ffbd2f1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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