gen_server
S = kvstore:start(). kvstore:set(name, "Colin", S). V = kvstore:fetch(name, S).
start() -> State = dict:new(), Handler = fun() -> loop(State) end, spawn(Handler). set(Key, Value, Pid) -> Pid ! {set, Key, Value}. fetch(Key, Pid) -> Pid ! {self(), {fetch, Key}}, receive Value -> Value end.
loop(State) -> receive {From, {fetch, Key}} -> {ok, Value} = dict:find(Key, State), From ! Value, loop(State); {set, Key, Value} -> NewState = dict:store(Key, Value, State), loop(NewState) end.
loop(State) -> receive {From, Message} -> {NewState, Value} = handle_call(Message, State), From ! Value; Message -> NewState = handle_cast(Message, State), end, loop(NewState). handle_call({fetch, Key}, State) -> {ok, Value} = dict:find(Key, State), {State, Value}. handle_cast({set, Key, Value}, State) -> dict:store(Key, Value, State).
loop/1
doesn’t know anything about the message contenthandle_call/2
and handle_cast/2
don’t know anything about message passing
increment(Key, Pid) -> Pid ! {self(), {increment, Key}}, receive Value -> Value end.
… and another handle_call/2
clause (no change to loop/1
)
handle_call({increment, Key}, State) -> NewState = dict:update_counter(Key, 1, State), {ok, Value} = dict:find(Key, NewState), {NewState, Value};
S = kvstore:start(). kvstore:set(age, 45, S). V = kvstore:increment(age, S).
cast(Message, Pid) -> Pid ! Message. call(Message, Pid) -> Pid ! {self(), Message}, receive Value -> Value end.
set(Key, Value, Pid) -> cast({set, Key, Value}, Pid). fetch(Key, Pid) -> call({fetch, Key}, Pid). increment(Key, Pid) -> call({increment, Key}, Pid).
start/0
start() -> State = init(), Handler = fun() -> loop(State) end, spawn(Handler). init() -> dict:new().
start/0
cast/2
call/2
loop/1
init/0
handle_cast/2
handle_call/2
set/3
fetch/2
increment/2
API | Generic | Plugin |
---|---|---|
start/0 | init/1 | |
set/3 | cast/2 | handle_cast/2 |
fetch/2 | call/2 | handle_call/2 |
increment/2 | ||
loop/1 |
terminate/2
)abcast
, multi_call