银行业务示例

这一节我们将展示如何结合BIF monitor_node/2和向远程节点的注册进程发送消息的能力。我们将实现一个非常简单的银行服务,用以处理远程站点的请求,比如ATM机上存款、取款业务。

程序6.1

  1. -module(bank_server).
  2. -export([start/0, server/1]).
  3.  
  4. start() ->
  5. register(bank_server, spawn(bank_server, server, [[]])).
  6.  
  7. server(Data) ->
  8. receive
  9. {From, {deposit, Who, Amount}} ->
  10. From ! {bank_server, ok},
  11. server(deposit(Who, Amount, Data));
  12. {From, {ask, Who}} ->
  13. From ! {bank_server, lookup(Who, Data)},
  14. server(Data);
  15. {From, {withdraw, Who, Amount}} ->
  16. case lookup(Who, Data) of
  17. undefined ->
  18. From ! {bank_server, no},
  19. server(Data);
  20. Balance when Balance > Amount ->
  21. From ! {bank_server, ok},
  22. server(deposit(Who, -Amount, Data));
  23. _ ->
  24. From ! {bank_server, no},
  25. server(Data)
  26. end
  27. end.
  28.  
  29. lookup(Who, [{Who, Value}|_]) -> Value;
  30. lookup(Who, [_|T]) -> lookup(Who, T);
  31. lookup(_, _) -> undefined.
  32.  
  33. deposit(Who, X, [{Who, Balance}|T]) ->
  34. [{Who, Balance+X}|T];
  35. deposit(Who, X, [H|T]) ->
  36. [H|deposit(Who, X, T)];
  37. deposit(Who, X, []) ->
  38. [{Who, X}].

程序6.1的代码运行于银行总部。而在出纳机(或分行)中执行的是程序6.2,该程序完成与总行服务器的交互。

程序6.2

  1. -module(bank_client).
  2. -export([ask/1, deposit/2, withdraw/2]).
  3.  
  4. head_office() -> 'bank@super.eua.ericsson.se'.
  5.  
  6. ask(Who) -> call_bank({ask, Who}).
  7. deposit(Who, Amount) -> call_bank({deposit, Who, Amount}).
  8. withdraw(Who, Amount) -> call_bank({withdraw, Who, Amount}).
  9. call_bank(Msg) ->
  10. Headoffice = head_office(),
  11. monitor_node(Headoffice, true),
  12. {bank_server, Headoffice} ! {self(), Msg},
  13. receive
  14. {bank_server, Reply} ->
  15. monitor_node(Headoffice, false),
  16. Reply;
  17. {nodedown, Headoffice} ->
  18. no
  19. end.

客户端程序定义了三个访问总行服务器的接口函数:

ask(Who)
返回客户Who的余额
deposit(Who,Amount)
给客户Who的帐户里面存入资金数Amount
withdraw(Who,Amount)
尝试从客户Who的帐户里面取出资金数Amount

函数call_bank/1实现了远程过程调用。一旦总行节点停止运作,call_bank/1将会及时发现,并返回no

总行节点的名称是硬编码在源码中的。在后续章节中我们将展示集中隐藏该信息的手段。