面对软件错误构建可靠的分布式系统_笔记07

4 编程技术

4.1抽象并出发

eg:thesis_server1.erl

-module(thesis_server1).
-export([start/3, stop/1, rpc/2]).

start(Name, F, State) ->
    register(Name, spawn(fun()->loop(Name, F, State) end)).

loop(Name, F, State) ->
    receive
      stop -> void;
          {Pid, Query} -> {Reply, State1} = F(Query, State),
          Pid ! {Name, Reply},
          loop(Name, F, State1)
end.    

stop(Name) -> Name ! stop.

rpc(Name, Query) ->
     Name ! {self(), Query},
     receive
          {Name, Reply} -> Reply
end.

 

thesis_vshlr1.erl

-module(thesis_vshlr1).
-export([start/0, stop/0, handle_event/2, i_am_at/2,find/1]).
-import(thesis_server1,[start/3,stop/1,rpc/2]).
-import(dict, [new/0, store/3, find/2]).

start() -> start(vshlr, fun handle_event/2, new()).

stop() ->stop(vshlr).

i_am_at(Who, Where) ->
    rpc(vshlr, {i_am_at, Who, Where}).
find(Who) ->
     rpc(vshlr, {find, Who}).
handle_event({i_am_at, Who, Where}, Dict) ->
     {ok, store(Who, Where, Dict)};
handle_event({find, Who}, Dict) ->
     {find(Who, Dict), Dict}. 

 

调用

1>thesis_vshlr1:start().

true

2>thesis_vshlr1:find("joe").

error

3>thesis_vshlr1:i_am_at("joe","sics").

ack

4>thesis_vshlr1:find"joe").

{ok,"sics"}


4.1.1 一个可容错的客户服务器模型

增加catch,可容错,其它同上
eg:thesis_server2.erl

-module(thesis_server2).
-export([start/3, stop/1, rpc/2]).

start(Name, F, State) ->
     register(Name, spawn(fun()->loop(Name, F, State) end)).

loop(Name, F, State) ->
     receive
          stop -> void;
          {From, Query} -> 
               case (catch F(Query, State)) of
                 {'EXIT', Why} ->
                     log(Name, Query, Why),
                     From ! {Name, crase},
                     loop(Name, F, State);
                {Reply, State1} ->
                      log(Name, ok, Reply),
                      From ! {Name, Reply},   
                      loop(Name, F, State1)
               end    
end.

 

stop(Name) -> Name ! stop.

 

rpc(Name, Query) ->
     Name ! {self(), Query},
     receive
          {Name, crash} -> exit(rpc);
          {Name, Reply} -> Reply
          after 1000 ->
               exit(timeout)
end.
 
log(Name, Query, Why) ->
     io:format("Server ~p is ~p by ~p~n",[Name, Query, Why]). 

thesis_vshlr2.erl      

-module(thesis_vshlr2).
-export([start/0, stop/0, handle_event/2, i_am_at/2,find/1]).
-import(thesis_server2,[start/3,stop/1,rpc/2]).
-import(dict, [new/0, store/3, find/2]).

start() -> start(vshlr, fun handle_event/2, new()).

 

stop() ->stop(vshlr).

 

i_am_at(Who, Where) ->
     rpc(vshlr, {i_am_at, Who, Where}).
 
find(Who) ->
     rpc(vshlr, {find, Who}).
 
handle_event({i_am_at, Who, Where}, Dict) ->
     {ok, store(Who, Where, Dict)};
handle_event({find, "myerror"}, Dict) ->
     1/0;
handle_event({find, Who}, Dict) ->
     {find(Who, Dict), Dict}. 

      

1>thesis_vshlr2:start().

true

2>thesis_vshlr2:find("myerror").

Server vshlr is {find,"myerror"} by {badarith,
                                     [{thesis_vshlr2,handle_event,2},
                                      {thesis_server2,loop,3}]}
crase
 

eg:thesis_server3.erl

热替换程序,(还有问题,没成功)

-module(thesis_server3).
-export([start/3, stop/1, rpc/2,swap_code/2]).

start(Name, F, State) ->
 register(Name, spawn(fun()->loop(Name, F, State) end)).

loop(Name, F, State) ->
 receive
  stop -> void;
  {From, {swap_code, Fnew}} ->
   From ! {Name,ok, ack},
   loop(Name, Fnew,State);
  {From, Query} -> 
   case (catch F(Query, State)) of
    {'EXIT', Why} ->
     log(Name, Query, Why),
     From ! {Name, crase},
     loop(Name, F, State);
    {Reply, State1} ->
      log(Name, ok, Reply),
      From ! {Name,ok, Reply},
      loop(Name, F, State1)
   end    
end.

stop(Name) -> Name ! stop.

swap_code(Name, F) ->
 rpc(Name, {swap_code, F}).

rpc(Name, Query) ->
 Name ! {self(), Query},
 receive
  {Name, crash} -> exit(rpc);
  {Name,ok, Reply} -> Reply
  after 1000 ->
   exit(timeout)
 end.
 
log(Name, Query, Why) ->
 io:format("Server ~p is ~p by ~p~n",[Name, Query, Why]). 
      

thesis_vshlr3.erl 

-module(thesis_vshlr3).
-export([start/0, stop/0, handle_event/2, i_am_at/2,find/1]).
-import(thesis_server3,[start/3,stop/1,rpc/2,swap_code/2]).
-import(dict, [new/0, store/3, find/2]).

start() -> start(vshlr, fun handle_event/2, new()).

stop() ->stop(vshlr).

i_am_at(Who, Where) ->
 rpc(vshlr, {i_am_at, Who, Where}).
 
find(Who) ->
 rpc(vshlr, {find, Who}).
 
handle_event({i_am_at, Who, Where}, Dict) ->
 {ok, store(Who, Where, Dict)};
handle_event({find, Who}, Dict) ->
 {find(Who, Dict), Dict}. 

 

1> thesis_server3:swap_code(thesis_vshlr1, fun(I,J)->thesis_vshlr1:handle_event(I,J) end).

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值