feat!: add custom ServerProcess module

main
Moritz Böhme 2024-08-03 10:14:19 +02:00
parent 09ae0c9bb3
commit 56ba54e2d7
Signed by: moritz
GPG Key ID: 970C6E89EB0547A9
1 changed files with 51 additions and 57 deletions

View File

@ -1,96 +1,90 @@
defmodule TodoServer do defmodule ServerProcess do
def start(entries \\ [], options \\ []) do def start(callback_module) do
pid = spawn(fn -> loop(TodoList.new(entries)) end) spawn(fn ->
initial_state = callback_module.init()
loop(callback_module, initial_state)
end)
end
if Keyword.get(options, :local) do defp loop(callback_module, current_state) do
Process.register(pid, :todo_list) receive do
{:call, request, caller} ->
{response, new_state} = callback_module.handle_call(request, current_state)
send(caller, {:response, response})
loop(callback_module, new_state)
{:cast, request} ->
new_state = callback_module.handle_cast(request, current_state)
loop(callback_module, new_state)
end end
pid
end end
def from_list(todo_list) do def call(pid, message) do
spawn(fn -> loop(todo_list) end) send(pid, {:call, message, self()})
receive do
{:response, response} ->
response
end
end end
defp loop(todo_list) do def cast(pid, message) do
new_todo_list = send(pid, {:cast, message})
receive do nil
message -> end
process_message(todo_list, message) end
after
1000 -> todo_list
end
loop(new_todo_list) defmodule TodoServer do
def init(entries) do
TodoList.new(entries)
end end
defp process_message(todo_list, {:add, entry}) do def handle_call({:entries, date}, todo_list) do
TodoList.add(todo_list, entry)
end
defp process_message(todo_list, {:entries, sender, date}) do
entries = TodoList.entries(todo_list, date) entries = TodoList.entries(todo_list, date)
send(sender, {:entries, entries}) {entries, todo_list}
end
def handle_call(invalid_message, todo_list) do
IO.puts("Invalid message: #{IO.inspect(invalid_message)}")
todo_list todo_list
end end
defp process_message(todo_list, {:update, id, update_fun}) do def handle_cast({:add, entry}, todo_list) do
TodoList.add(todo_list, entry)
end
def handle_cast({:update, id, update_fun}, todo_list) do
TodoList.update(todo_list, id, update_fun) TodoList.update(todo_list, id, update_fun)
end end
defp process_message(todo_list, {:delete, id}) do def handle_cast({:delete, id}, todo_list) do
TodoList.delete(todo_list, id) TodoList.delete(todo_list, id)
end end
defp process_message(todo_list, invalid_message) do def handle_cast(invalid_message, todo_list) do
IO.puts("Invalid message: #{IO.inspect(invalid_message)}") IO.puts("Invalid message: #{IO.inspect(invalid_message)}")
todo_list todo_list
end end
def add(pid, entry) do def add(pid, entry) do
send(pid, {:add, entry}) ServerProcess.cast(pid, {:add, entry})
nil
end
def add(entry) do
add(:todo_list, entry)
end end
def entries(pid, date) do def entries(pid, date) do
send(pid, {:entries, self(), date}) ServerProcess.call(pid, {:entries, date})
receive do
{:entries, value} ->
{:ok, value}
after
1000 -> {:error}
end
end
def entries(date) do
entries(:todo_list, date)
end end
def update(pid, id, update_fun) do def update(pid, id, update_fun) do
send(pid, {:update, id, update_fun}) ServerProcess.cast(pid, {:update, id, update_fun})
nil
end
def update(id, update_fun) do
update(:todo_list, id, update_fun)
end end
def delete(pid, id) do def delete(pid, id) do
send(pid, {:delete, id}) ServerProcess.cast(pid, {:delete, id})
nil
end
def delete(id) do
delete(:todo_list, id)
end end
end end