Chinaunix首页 | 论坛 | 博客
  • 博客访问: 204530
  • 博文数量: 39
  • 博客积分: 1057
  • 博客等级: 准尉
  • 技术积分: 926
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-27 20:13
文章分类

全部博文(39)

文章存档

2012年(24)

2011年(15)

分类: Python/Ruby

2012-06-12 09:50:41

这里是对gen_server一段的摘抄。描述了gen_server必须的6个方法的用途和性质

16.3 The gen_server Callback Structure

Now that we've got the idea,we'll take a more detailed look at the gen_server callback structure.

What Happens When We Start the Server?
The call gen_server:start_link(Name,Mod,initArgs,Opts) starts everything.It creates a generic server called Name.The callback module is Mod.Opts controls the behavior of the generic server.Here we can specify logging of message,debugging functions,and so on.The generic server starts by calling Mod:init(initArgs).

The template entry for init is as follows:

 %% Function: init(Args) -> {ok,State}  |
 %%                          {ok,State,Timeout} |
 %%                          ignore      |
 %%                          {stop,Reason}
 %% Description: Initiates the server
init([]) ->
    {ok,#state{}}.
In normal operation,we just return {ok,State}.For the meaning of the other arguments,consult the manual page for gen_server.

If {ok,State} is returned,then we have successfully started the server,and the initial state the State.

What happens When We Call the Server?
To call the server,the client program calls gen_server:call(Name,Request).This results in handle_call/3 in the callback module being called.

handle_call/3 has the following template entry:

%% Function: handle_call(Request,From,State) -> {reply,Reply,State}  |
%%                                              {reply,Reply,State,Timeout} |
%%                                              {noreply,State}      |
%%                                              {noreply,State,Timeout} |
%%                                              {stop,Reason,Reply,State} |
%%                                              {stop,Reason,State}
%% Description: Handling call message
handle_call(_Request,_From,State) ->
    Reply = ok,
    {reply,Reply,State}.

Request (the second argument of gen_server:call/2) reappears as the first argument of handle_call/3.From is the Pid of the requesting client process,and State is the current state of the client.

Normally we return {reply,Reply,NewState}.When this happens,Reply goes back to client,where it becomes the return value of gen_server:call.NewState
is the next state of the server.

The other return values,{noreply,...} and {stop,...},are used relatively infrequently.no reply causes the server to continue,but the client will wait for reply so the server will have to delegate the task of replying to some other process.Calling stop with the appropriate arguments will stop the server.

Calls and Casts
We've seen the interplay between gen_server:call and handle_call.This is used for implementing remote procedure calls.gen_server:cast(Name,Request) implements a cast,which is just a call with no return value (actually just a message,but traditionally it's called a cast to distinguish it from a remote procedure call).

The corresponding callback routine is handle_cast;the template entry is like this:
%% Function: handle_cast(Msg,State) -> {noreply,NewState} |
%%                                     {noreply,NewState,Timeout} |
%%                                     {stop,Reason,NewState}
%% Description: Handling cast messages
handle_cast(Msg,State) ->
    {noreply,NewState}.

The handler usually jsut returns {noreply,NewState},which changes the state of the server,or {stop,...},which stops the server.

Spontaneous Messages to the Server
The callback function handle_info(Info,State) is used to handling spontaneous messages to the server.So,what's a spontaneous messges? If the server is linked to anthor process and is trapping exits,then it might suddenly receive a unexpected {'EXIT',Pid,What} messages.Alternativly,any process in the system that discovers the PID of the generic server can just send it messagge. Any message like this ends up at the server as the value of info.

The template entry for handle_info is as follows:
%% Function: handle_info(Info,State) -> {noreply,State} |
%%                                      {noreply,State,Timeout} |
%%                                      {stop,Reason,State}
%% Description: Handling all non-call/cast messages
handle_info(_Info,State) ->
    {noreply,State}.

The return values are the same as for handle_cast.

Hasta la Vista,Baby
The server can terminate for many reasons.One of the handle_Somehting routines might return a {stop,Reason,NewState},or the server might crash with {'EXIT',reason}.In all of these circumstances,no matter how they occurred.terminate(Reason,NewState) will be called.

Here's the template:
%% Funciton: terminate(Reason,State) -> void()
%% Description: This function is called by a gen_server when it is about to terminate.It should be the opposite of Module:init/1 and do any necessary
%% cleaning up.when it returns,the gen_server terminates with Reason.
%% The return value is ignored.
terminate(_Reason,State) ->
    ok.
This code can't return a new state because we've terminated.So,what can we do with state? Lots of things,it turns out.We could store it on disk,send it in a message to some other process,or discard it depending upon the application.If you want your server to be restarted in the future,you'll have to write an "I'll be back" function that is triggered by terminate/2.

Code Change
You can dynamically change the state of your server while it is running.This callback function is called by the release handling subsystem when the system performs a software upgrade.

This topic is described in detail in the section on release handling in the OPT design principles documentation.
%% Function: code_change(_OldVsn,State,_Extra) -> {ok,NewState}.
%% Description: Convert process state when code is changed
code_change(_OldVsn,State,_Extra) -> {ok,State}.

阅读(1496) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~