在实现了一个基础的服务器之后,现在来实现一下一个实现了事务的服务器。下面这个服务器会在查询产生异常错误时让客户端崩溃。
-module(server2).
-author("DQ").
%% API
-export([start/2, rpc/2]).
start(Name, Mod) ->
register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)).
rpc(Name, Request) ->
Name ! {self(), Request},
receive
{Name, crash} -> exit(rpc);
{Name, ok, Response} -> Response
end.
loop(Name, Mod, OldState) ->
receive
{From, Request} ->
try Mod:handle(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]).
这段代码在服务器里实现了“事务语义”,它会在处理函数抛出异常错误时用State(状态) 的初始值继续循环。但如果处理函数成功了,它就会用处理函数提供的NewState值继续循环。 当处理函数失败时,服务器会给发送问题消息的客户端发送一个消息,让它崩溃。这个客户 端不能继续工作,因为它发送给服务器的请求导致了处理函数的崩溃,但其他想要使用服务器的 客户端不会受到影响。另外,当处理函数发生错误时,服务器的状态不会改变。