diff options
-rw-r--r-- | common/server.erl | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/common/server.erl b/common/server.erl index 67fb000..713a443 100644 --- a/common/server.erl +++ b/common/server.erl @@ -8,56 +8,78 @@ -export([start/2, start/3, start_on_node/3, rpc/2]). start(Name, Mod) -> - register(Name, spawn(fun() -> loop(Mod, Mod:init()) end)). + %% like start/3 but call Mod:init() for getting the initial state + start(Name, Mod, Mod:init()). start(Name, Mod, State) -> + %% start a server with the given initial State and register it as + %% Name register(Name, spawn(fun() -> loop(Mod, State) end)). start_on_node(Node, Mod, State) -> + %% link start/3 but start the process on the given Node and not + %% register it (only local processes could be registered) spawn(Node, fun() -> loop(Mod, State) end). wait_response(_, Ref) -> + %% wait for a specific reponse form the server receive {Ref, crash} -> exit(rpc); {Ref, ok, Response} -> Response end. rpc(Client, Request) -> + %% make a call to the given client (make a reference to find the + %% corresponding response) Ref = make_ref(), Client ! {Ref, self(), Request}, wait_response(Client, Ref). loop(Mod, OldState) -> + %% main lopp receive + %% pattern, that is matched if a message is directly sended to + %% a server (like register and login called form the client + %% over the dispatcher) {From, Request} -> try Mod:handle(Request, OldState) of {Response, NewState} -> From ! {ok, Response}, loop(Mod, NewState) catch - _: Why -> + %% log error if handle function is not working + %% correctly and report the crash to the sender + _: Why -> log_the_error(Request, Why), From ! {crash}, loop(Mod, OldState) end; + %% pattern is matched if rpc/2 is used, response is send with + %% the received reference to match the correct response {Ref, From, Request} when is_reference(Ref) -> try Mod:handle(Request, OldState) of {Response, NewState} -> From ! {Ref, ok, Response}, loop(Mod, NewState) catch + %% log error if handle function is not working + %% correctly and report the crash to the sender _: Why -> log_the_error(Request, Why), From ! {Ref, crash}, loop(Mod, OldState) end; + %% handle messages if a linked process emits an error (no + %% response to sender nessessary, sender is dead) {'EXIT', From, Why} -> try Mod:handle({'EXIT', From, Why}, OldState) of NewState -> loop(Mod, NewState) catch + %% log error if handle function is not working + %% correctly and report the crash to the sender _: Why -> log_the_error('EXIT', Why), loop(Mod, OldState) @@ -65,6 +87,5 @@ loop(Mod, OldState) -> end. log_the_error(Request, Why) -> - io:format("Server request ~p ~n" - "caused exception ~p~n", - [Request, Why]). + %% helper function to log an error + io:format("Server request ~p caused exception ~p~n", [Request, Why]). |