defmodule Todo.DatabaseWorker do use GenServer def start_link({_db_folder, worker_id} = state) do GenServer.start_link(__MODULE__, state, name: via_tuple(worker_id)) end def store(worker_id, key, data) do worker_id |> via_tuple() |> GenServer.cast({:store, key, data}) end def get(worker_id, key) do worker_id |> via_tuple() |> GenServer.call({:get, key}) end defp via_tuple(worker_id) do Todo.ProcessRegistry.via_tuple({__MODULE__, worker_id}) end @impl GenServer def init({db_folder, worker_id} = state) do IO.puts("Starting #{__MODULE__} #{worker_id} with db folder #{db_folder}.") {:ok, state} end @impl GenServer def handle_cast({:store, key, data}, {db_folder, _worker_id} = state) do {db_folder, key} |> file_name() |> File.write!(:erlang.term_to_binary(data)) {:noreply, state} end @impl GenServer def handle_call({:get, key}, _, {db_folder, _worker_id} = state) do data = case File.read(file_name({db_folder, key})) do {:ok, contents} -> :erlang.binary_to_term(contents) {:error, :enoent} -> nil end {:reply, data, state} end def file_name({db_folder, key}) do Path.join(db_folder, to_string(key)) end end