Skip to content

Instantly share code, notes, and snippets.

@mururu

mururu/kvs.ex Secret

Last active July 19, 2021 10:49
Show Gist options
  • Save mururu/17c489dac3d6b2b24528 to your computer and use it in GitHub Desktop.
Save mururu/17c489dac3d6b2b24528 to your computer and use it in GitHub Desktop.
samples for shinjuku.ex #10
## がんばったやつ
defmodule GServer do
def start(mod) do
spawn(fn() ->
state = mod.init
loop({mod, state})
end)
end
def cast(pid, request) do
send(pid, {:cast, request})
:ok
end
def call(pid, request) do
ref = Process.monitor(pid)
send(pid, {:call, self(), ref, request})
receive do
{^ref, result} ->
Process.demonitor(ref, [:flush])
result
{:DOWN, ^ref, :process, ^pid, reason} ->
exit(reason)
end
end
defp loop({mod, state}) do
receive do
{:cast, request} ->
state = mod.handle_cast(request, state)
loop({mod, state})
{:call, pid, ref, request} ->
{result, state} = mod.handle_call(request, state)
send(pid, {ref, result})
loop({mod, state})
end
end
end
defmodule KVS do
def start do
GServer.start(__MODULE__)
end
def put(pid, key, value) do
GServer.cast(pid, {:put, key, value})
end
def delete(pid, key) do
GServer.cast(pid, {:delete, key})
end
def get(pid, key) do
GServer.call(pid, {:get, key})
end
def get_and_update(pid, key, value) do
GServer.call(pid, {:get_and_update, key, value})
end
## callbacks
def init do
HashDict.new
end
def handle_cast({:put, key, value}, state) do
Dict.put(state, key, value)
end
def handle_cast({:delete, key}, state) do
Dict.delete(state, key)
end
def handle_call({:get, key}, state) do
{state[key], state}
end
def handle_call({:get_and_update, key, value}, state) do
{state[key], Dict.put(state, key, value)}
end
end
## GenServer を使うと
defmodule KVS do
use GenServer
def start do
GenServer.start(__MODULE__, :ok)
end
def put(pid, key, value) do
GenServer.cast(pid, {:put, key, value})
end
def delete(pid, key) do
GenServer.cast(pid, {:delete, key})
end
def get(pid, key) do
GenServer.call(pid, {:get, key})
end
def get_and_update(pid, key, value) do
GenServer.call(pid, {:get_and_update, key, value})
end
## callbacks
def init(:ok) do
{:ok, HashDict.new}
end
def handle_cast({:put, key, value}, state) do
{:noreply, Dict.put(state, key, value)}
end
def handle_cast({:delete, key}, state) do
{:noreply, Dict.delete(state, key)}
end
def handle_call({:get, key}, _from, state) do
{:reply, state[key], state}
end
def handle_call({:get_and_update, key, value}, _from, state) do
{:reply, state[key], Dict.put(state, key, value)}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment