defmodule Todo.Database do alias Todo.DatabaseWorker use GenServer @db_folder "./persist" @num_of_workers 3 def start do GenServer.start(__MODULE__, nil, name: __MODULE__) end def store(key, data) do GenServer.cast(__MODULE__, {:store, key, data}) end def get(key) do GenServer.call(__MODULE__, {:get, key}) end @impl GenServer def init(_) do File.mkdir_p!(@db_folder) {:ok, nil, {:continue, :init}} end @impl GenServer def handle_continue(:init, nil) do File.mkdir_p!(@db_folder) workers = 0..(@num_of_workers - 1) |> Enum.map(fn i -> {:ok, pid} = Todo.DatabaseWorker.start(@db_folder) {i, pid} end) |> Map.new() IO.inspect(workers) {:noreply, workers} end @impl GenServer def handle_cast({:store, key, data}, workers) do workers |> get_worker(key) |> DatabaseWorker.store(key, data) {:noreply, workers} end @impl GenServer def handle_call({:get, key}, _, workers) do data = workers |> get_worker(key) |> DatabaseWorker.get(key) {:reply, data, workers} end defp choose_worker(workers, key) do id = :erlang.phash2(key, @num_of_workers) Map.fetch!(workers, id) end end