熱代碼交換:如果要修改一個服務器的行爲,不用停止它,只需要發送一個包含新代碼的消息,它就會提取新代碼,然後用新代碼和老代碼
的回話數據繼續工作。
編寫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}.
Erlang — gen_server
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
Erlang rpc函數初學
Edison
2018-08-27 18:53:23
Erlang防止同時註冊同一個進程
Edison
2018-08-27 18:53:17
Erlang併發程序模版
Edison
2018-08-27 18:53:17
Erlang開發建議(雜記版)
iteye_18554
2018-08-27 16:13:54
Erlang類型及函數聲明規格
iteye_18554
2018-08-27 16:13:53
inet:getstat/2小用法
iteye_18554
2018-08-27 16:13:53
Erlang定時任務server (仿crontab語法)
iteye_18554
2018-08-27 16:13:51
Erlang遊戲開發-協議
iteye_18554
2018-08-27 16:13:51
list random shuffle實現
iteye_18554
2018-08-27 16:13:51
用Erlang做了很多事
iteye_18554
2018-08-27 16:13:51
Gearman Erlang Client
iteye_18554
2018-08-27 16:13:51
Erlang進程之錯?
iteye_18554
2018-08-27 16:13:51
gen-erl-app快速生成erlang app 框架
iteye_18554
2018-08-27 16:13:51
erl-redis發佈
iteye_18554
2018-08-27 16:13:50
ECUG歸來
iteye_18554
2018-08-27 16:13:50