1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
%% Inspired by "Programming Erlang",
%% published by The Pragmatic Bookshelf.
%% Copyrights apply to this code.
%% We make no guarantees that this code is fit for any purpose.
%% Visit http://www.pragmaticprogrammer.com/titles/jaerlang for more book information.
-module(server).
-export([start/2, start/3, rpc/2, swap_code/2]).
start(Name, Mod) ->
register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)).
start(Name, Mod, State) ->
register(Name, spawn(fun() -> loop(Name, Mod, State) end)).
swap_code(Name, Mod) -> rpc(Name, {swap_code, Mod}).
rpc(Name, Request) ->
Name ! {self(), Request},
receive
{Name, crash} -> exit(rpc);
{Name, ok, Response} -> Response
end.
loop(Name, Mod, OldState) ->
receive
{From, {swap_code, NewCallbackMod}} ->
From ! {Name, ok, ack},
loop(Name, NewCallbackMod, OldState);
{From, Request} ->
{Response, NewState} = Mod:handle(From, Request, OldState),
From ! {Name, ok, Response},
loop(Name, Mod, NewState)
%% try Mod:handle(From, Request, OldState) of
%% {Response, NewState} ->
%% From ! {Name, ok, Response},
%% loop(Name, Mod, NewState)
%% catch
%% _: Why ->
%% log_the_error(Name, Request, Why),
%% From ! {Name, crash},
%% loop(Name, Mod, OldState)
%% end
end.
log_the_error(Name, Request, Why) ->
io:format("Server ~p request ~p ~n"
"caused exception ~p~n",
[Name, Request, Why]).
|