Compare commits
No commits in common. "1550e896a072869fdd966d511ebc68d1b408ae50" and "8355f3094813e85bd8ef28bff22d72d824361858" have entirely different histories.
1550e896a0
...
8355f30948
5 changed files with 47 additions and 161 deletions
|
@ -3,7 +3,6 @@ defmodule Todo.Cache do
|
||||||
|
|
||||||
@impl GenServer
|
@impl GenServer
|
||||||
def init(_init_args) do
|
def init(_init_args) do
|
||||||
Todo.Database.start()
|
|
||||||
{:ok, %{}}
|
{:ok, %{}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -14,7 +13,7 @@ defmodule Todo.Cache do
|
||||||
{:reply, process, state}
|
{:reply, process, state}
|
||||||
|
|
||||||
:error ->
|
:error ->
|
||||||
{:ok, new_process} = Todo.Server.start(name)
|
new_process = Todo.Server.start()
|
||||||
|
|
||||||
new_state = Map.put(state, name, new_process)
|
new_state = Map.put(state, name, new_process)
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
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
|
|
|
@ -1,48 +0,0 @@
|
||||||
defmodule Todo.DatabaseWorker do
|
|
||||||
use GenServer
|
|
||||||
|
|
||||||
def start(db_folder) do
|
|
||||||
GenServer.start(__MODULE__, db_folder)
|
|
||||||
end
|
|
||||||
|
|
||||||
def store(pid, key, data) do
|
|
||||||
GenServer.cast(pid, {:store, key, data})
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(pid, key) do
|
|
||||||
GenServer.call(pid, {:get, key})
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def init(db_folder) do
|
|
||||||
{:ok, db_folder}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_cast({:store, key, data}, db_folder) do
|
|
||||||
{db_folder, key}
|
|
||||||
|> file_name()
|
|
||||||
|> File.write!(:erlang.term_to_binary(data))
|
|
||||||
|
|
||||||
{:noreply, db_folder}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_call({:get, key}, _, db_folder) do
|
|
||||||
data =
|
|
||||||
case File.read(file_name({db_folder, key})) do
|
|
||||||
{:ok, contents} ->
|
|
||||||
:erlang.binary_to_term(contents)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
{:reply, data, db_folder}
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_name({db_folder, key}) do
|
|
||||||
Path.join(db_folder, to_string(key))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,8 +1,52 @@
|
||||||
defmodule Todo.Server do
|
defmodule Todo.Server do
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
def start(name) do
|
@impl GenServer
|
||||||
GenServer.start(__MODULE__, name)
|
def init(%_{} = todo_list) do
|
||||||
|
{:ok, todo_list}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl GenServer
|
||||||
|
def init(entries) do
|
||||||
|
{:ok, Todo.List.new(entries)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl GenServer
|
||||||
|
def handle_call({:entries, date}, _from, todo_list) do
|
||||||
|
entries = Todo.List.entries(todo_list, date)
|
||||||
|
|
||||||
|
{:reply, entries, todo_list}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl GenServer
|
||||||
|
def handle_cast({:add, entry}, todo_list) do
|
||||||
|
new_todo_list = Todo.List.add(todo_list, entry)
|
||||||
|
|
||||||
|
{:noreply, new_todo_list}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl GenServer
|
||||||
|
def handle_cast({:update, id, update_fun}, todo_list) do
|
||||||
|
new_todo_list = Todo.List.update(todo_list, id, update_fun)
|
||||||
|
|
||||||
|
{:noreply, new_todo_list}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl GenServer
|
||||||
|
def handle_cast({:delete, id}, todo_list) do
|
||||||
|
new_todo_list = Todo.List.delete(todo_list, id)
|
||||||
|
|
||||||
|
{:noreply, new_todo_list}
|
||||||
|
end
|
||||||
|
|
||||||
|
def start(entries \\ [])
|
||||||
|
|
||||||
|
def start(%_{} = todo_list) do
|
||||||
|
GenServer.start(__MODULE__, todo_list)
|
||||||
|
end
|
||||||
|
|
||||||
|
def start(entries) do
|
||||||
|
GenServer.start(__MODULE__, entries)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(pid, entry) do
|
def add(pid, entry) do
|
||||||
|
@ -20,46 +64,4 @@ defmodule Todo.Server do
|
||||||
def delete(pid, id) do
|
def delete(pid, id) do
|
||||||
GenServer.cast(pid, {:delete, id})
|
GenServer.cast(pid, {:delete, id})
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def init(name) do
|
|
||||||
{:ok, {name, nil}, {:continue, :init}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_continue(:init, {name, nil}) do
|
|
||||||
todo_list = Todo.Database.get(name) || Todo.List.new()
|
|
||||||
{:noreply, {name, todo_list}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_call({:entries, date}, _from, {name, todo_list}) do
|
|
||||||
entries = Todo.List.entries(todo_list, date)
|
|
||||||
|
|
||||||
{:reply, entries, {name, todo_list}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_cast({:add, entry}, {name, todo_list}) do
|
|
||||||
new_todo_list = Todo.List.add(todo_list, entry)
|
|
||||||
Todo.Database.store(name, new_todo_list)
|
|
||||||
|
|
||||||
{:noreply, {name, new_todo_list}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_cast({:update, id, update_fun}, {name, todo_list}) do
|
|
||||||
new_todo_list = Todo.List.update(todo_list, id, update_fun)
|
|
||||||
Todo.Database.store(name, new_todo_list)
|
|
||||||
|
|
||||||
{:noreply, {name, new_todo_list}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl GenServer
|
|
||||||
def handle_cast({:delete, id}, {name, todo_list}) do
|
|
||||||
new_todo_list = Todo.List.delete(todo_list, id)
|
|
||||||
Todo.Database.store(name, new_todo_list)
|
|
||||||
|
|
||||||
{:noreply, {name, new_todo_list}}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
BIN
persist/a
BIN
persist/a
Binary file not shown.
Loading…
Reference in a new issue