Erlang — gen_server

熱代碼交換:如果要修改一個服務器的行爲,不用停止它,只需要發送一個包含新代碼的消息,它就會提取新代碼,然後用新代碼和老代碼
            的回話數據繼續工作。


編寫gen_server回調模塊的簡要步驟:
   
   1、確定回調模塊名。


   2、編寫接口函數。


   3、在回調模塊裏編寫六個必需的回調函數。




  在回調模塊中必須導出六個回調方法:init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3


   簡單的回調模板:
    
   -module(gen_server_template).
   -behaviour(gen_server).
   %% ====================================================================
   %% gen_server 回調行數
   %% ====================================================================
   -export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
   -record(state,{}).


   init([]) ->
        {ok,#state{}}.


   handle_call(_Request,_From,State) ->
Replay = ok,
{replay,Replay,State}.


   handle_cast(_Msg,State) ->
{noreplay,State}.


   handle_info(_Info,State) ->
{ok,State}.


  terminate(_Reason,_State) ->
ok.


  code_change(_OldVsn,State,_Extra) ->
{ok,State}.




 對於通用服務器而言,用戶主要完成以下兩件事:
  
   1、啓動服務器進程


   2、向進程發消息(並獲取應答)


 gen_server提供了三個主要的庫函數來實現這些基本功能:
  
  ---------------------------------------------------------------------------------------------------------------------------------------
     庫函數                         對應回調函數                          描述
  ---------------------------------------------------------------------------------------------------------------------------------------
    gen_server:start_link/4         Module:init/1               啓動並鏈接一個gen_server容器進程


    gen_server:call/2               Module:handle_call/3        向gen_server進程發送同步消息並等待應答


    gen_server:case/2               Module:handle_cast/2        向gen_server進程發送異步消息
  ----------------------------------------------------------------------------------------------------------------------------------------


 注:gen_server:call/2 函數實現了可靠的同步請求—響應功能,其中默認應答等待超時爲5秒,一旦超時便放棄等待應答,
   
     gen_server:call/3 允許以毫秒爲單位設置超時,同時也可以通過將超時時間設置爲infinity來禁用超時。


     handle_info/2 沒有對應的gen_server庫函數,這個回調是一個重要的特例,所有未經過call或cast庫函數發送至gen_server
  
     信箱的消息都由它處理(通常是直接用!運算符發送的裸消息)。


  gen_server:start_link({local,?SERVER}?MODULE,[port],[]).執行這個調用的時候,會派生出一個新的gen_server容器
   
  進程,新進程將以SERVER宏展開後對於的名稱在本地節點上註冊,然後等待行爲模式實現模塊中的init/1回調函數完成進程
  
  初始化,最後返回。




  example:


%%% @author xiaomage
%%% @doc 模擬銀行開戶、存款、取款操作
%%% @todo Add description to my_banck.




-module(my_banck).
-behaviour(gen_server).
-define(SERVER,?MODULE).


%%-------------------------------
%% gen_server call_back function
%%-------------------------------
-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).


%%-------------------------------
%% API function
%%-------------------------------
-export([start/0,stop/0,new_account/1,deposit/2,withdraw/2]).


start() ->
gen_server:start_link({local,?SERVER}, ?MODULE, [], []).


stop() ->
gen_server:call(?MODULE, stop).


new_account(Who) ->
gen_server:call(?MODULE, {new,Who}).


deposit(Who,Amount) ->
gen_server:call(?MODULE, {add,Who,Amount}).


withdraw(Who,Amount) ->
gen_server:call(?MODULE, {remove,Who,Amount}).





init([]) ->
{ok,ets:new(?MODULE, [])}.


handle_call({new,Who},_From,Tab) ->
Reply = case ets:lookup(Tab, Who) of
[] -> 
ets:insert(Tab, {Who,0}),
{welcome,Who};
[_] ->
{Who,you_are_already_a_customer}
end,
{reply,Reply,Tab};


handle_call({add,Who,X},_From,Tab) ->
Reply = case ets:lookup(Tab, Who) of
[] ->
not_a_customer;
[{Who,Amount}] ->
NewAmount = Amount + X,
ets:insert(Tab, {Who,NewAmount}),
{thanks,Who,you_banck_is ,NewAmount}
             end,
    {reply,Reply,Tab};


handle_call({remove,Who,X},_From,Tab) ->
Reply = case ets:lookup(Tab, Who) of
[] ->
not_a_customer;
[{Who,Amount}] when Amount >= X ->
NewAmount = Amount - X,
ets:insert(Tab, {Who,NewAmount}),
{thanks,Who,you_banck_is,NewAmount};
[{Who,Amount}] ->
{sorry,Who,you_only_hava,Amount,in_the_banck}
end,
{reply,Reply,Tab};

handle_call({stop}, _From, Tab) ->
{stop,normal,stopped,Tab}.




handle_cast(_Msg,State) ->
{noreply,State}.


handle_info(_Info,State) ->
{ok,State}.


terminate(_Reason,_State) ->
ok.


code_change(_OldVsn,State,_Extra) ->
{ok,State}.



























































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章