defmodule SApp.BlockStore do @moduledoc """ A module that implements a content-adressable storage (blocks, or pages, identified by the hash of their contents). Establishes full node connectivity and uses rendez-vous hashing to select which nodes are responsible of a given hash. TODO: WIP """ use GenServer defmodule State do defstruct [:name, :id, :manifest, :ncopies, :store, :peers] end def start_link(name) do GenServer.start_link(__MODULE__, name) end def init(name) do manifest = {:blockstore, name} id = SData.term_hash manifest GenServer.cast(Shard.Manager, {:register, id, self()}) GenServer.cast(self(), :init_pull) {:ok, %State{name: name, id: id, manifest: manifest, ncopies: 3, store: %{}, peers: %{}}} end def handle_call(:manifest, _from, state) do {:reply, state.manifest, state} end def handle_call({:get, key}, from, state) do # TODO end def handle_call({:put, val}, state) do # TODO end def handle_cast({:redundant, _}, _state) do exit :normal end def handle_cast(:init_pull, state) do GenServer.call(SNet.Manager, :get_all) |> Enum.each(&(GenServer.cast(&1, {:send_msg, {:interested, [state.id]}}))) {:noreply, state} end def handle_cast({:interested, peer_id, peer_pid}, state) do new_peers = Map.put(state.peers, peer_id, peer_pid) new_state = %{ state | peers: new_peers } initial_sync(new_state, peer_id, peer_pid) {:noreply, new_state} end def handle_cast({:msg, peer_id, peer_pid, msg}, state) do # TODO {:noreply, state} end defp initial_sync(state, peer_id, peer_pid) do # TODO end defp send(state, to, msg) do GenServer.cast(to, {:send_msg, {state.id, msg}}) end end