`
coderplay
  • 浏览: 576817 次
  • 性别: Icon_minigender_1
  • 来自: 广州杭州
社区版块
存档分类
最新评论

OTP设计原则:Gen_Server行为

阅读更多

2 Gen_Server Behaviour


This chapter should be read in conjunction with gen_server(3), where all interface functions and callback functions are described in detail.

2.1 Client-Server Principles

The client-server model is characterized by a central server and an arbitrary number of clients. The client-server model is generally used for resource management operations, where several different clients want to share a common resource. The server is responsible for managing this resource.

clientserver
Client-Server Model 客户-服务器模型

2.2 Example

An example of a simple server written in plain Erlang was given in Overview. The server can be re-implemented using gen_server, resulting in this callback module:

java 代码
 
  1. -module(ch3).  
  2. -behaviour(gen_server).  
  3.   
  4. -export([start_link/0]).  
  5. -export([alloc/0, free/1]).  
  6. -export([init/1, handle_call/3, handle_cast/2]).  
  7.   
  8. start_link() ->  
  9.     gen_server:start_link({local, ch3}, ch3, [], []).  
  10.   
  11. alloc() ->  
  12.     gen_server:call(ch3, alloc).  
  13.   
  14. free(Ch) ->  
  15.     gen_server:cast(ch3, {free, Ch}).  
  16.   
  17. init(_Args) ->  
  18.     {ok, channels()}.  
  19.   
  20. handle_call(alloc, _From, Chs) ->  
  21.     {Ch, Chs2} = alloc(Chs),  
  22.     {reply, Ch, Chs2}.  
  23.   
  24. handle_cast({free, Ch}, Chs) ->  
  25.     Chs2 = free(Ch, Chs),  
  26.     {noreply, Chs2}.  


The code is explained in the next sections.

2.3 Starting a Gen_Server

In the example in the previous section, the gen_server is started by calling ch3:start_link():

java 代码
  1. start_link() ->  
  2.     gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}  


start_link calls the function gen_server:start_link/4. This function spawns and links to a new process, a gen_server.

  • The first argument {local, ch3} specifies the name. In this case, the gen_server will be locally registered as ch3.
    If the name is omitted, the gen_server is not registered. Instead its pid must be used. The name could also be given as {global, Name}, in which case the gen_server is registered using global:register_name/2.
  • The second argument, ch3, is the name of the callback module, that is the module where the callback functions are located.
    In this case, the interface functions (start_link, alloc and free) are located in the same module as the callback functions (init, handle_call and handle_cast). This is normally good programming practice, to have the code corresponding to one process contained in one module.
  • The third argument, [], is a term which is passed as-is to the callback function init. Here, init does not need any indata and ignores the argument.
  • The fourth argument, [], is a list of options. See gen_server(3) for available options.

If name registration succeeds, the new gen_server process calls the callback function ch3:init([]). init is expected to return {ok, State}, where State is the internal state of the gen_server. In this case, the state is the available channels.

java 代码
  1. init(_Args) ->  
  2.     {ok, channels()}.  


Note that gen_server:start_link is synchronous. It does not return until the gen_server has been initialized and is ready to receive requests.

gen_server:start_link must be used if the gen_server is part of a supervision tree, i.e. is started by a supervisor. There is another function gen_server:start to start a stand-alone gen_server, i.e. a gen_server which is not part of a supervision tree.

2.4 Synchronous Requests - Call

The synchronous request alloc() is implemented using gen_server:call/2:

java 代码
  1. alloc() ->  
  2.     gen_server:call(ch3, alloc).  


ch3 is the name of the gen_server and must agree with the name used to start it. alloc is the actual request.

The request is made into a message and sent to the gen_server. When the request is received, the gen_server calls handle_call(Request, From, State) which is expected to return a tuple {reply, Reply, State1}. Reply is the reply which should be sent back to the client, and State1 is a new value for the state of the gen_server.

java 代码
  1. handle_call(alloc, _From, Chs) ->  
  2.     {Ch, Chs2} = alloc(Chs),  
  3.     {reply, Ch, Chs2}.  


In this case, the reply is the allocated channel Ch and the new state is the set of remaining available channels Chs2.

Thus, the call ch3:alloc() returns the allocated channel Ch and the gen_server then waits for new requests, now with an updated list of available channels.

2.5 Asynchronous Requests - Cast

The asynchronous request free(Ch) is implemented using gen_server:cast/2:

java 代码
  1. free(Ch) ->  
  2.     gen_server:cast(ch3, {free, Ch}).  


ch3 is the name of the gen_server. {free, Ch} is the actual request.

The request is made into a message and sent to the gen_server. cast, and thus free, then returns ok.

When the request is received, the gen_server calls handle_cast(Request, State) which is expected to return a tuple {noreply, State1}. State1 is a new value for the state of the gen_server.

java 代码
  1. handle_cast({free, Ch}, Chs) ->  
  2.     Chs2 = free(Ch, Chs),  
  3.     {noreply, Chs2}.  


In this case, the new state is the updated list of available channels Chs2. The gen_server is now ready for new requests.

2.6 Stopping


2.6.1 In a Supervision Tree

If the gen_server is part of a supervision tree, no stop function is needed. The gen_server will automatically be terminated by its supervisor. Exactly how this is done is defined by a shutdown strategy set in the supervisor.

If it is necessary to clean up before termination, the shutdown strategy must be a timeout value and the gen_server must be set to trap exit signals in the init function. When ordered to shutdown, the gen_server will then call the callback function terminate(shutdown, State):

java 代码
 
  1. init(Args) ->  
  2.     ...,  
  3.     process_flag(trap_exit, true),  
  4.     ...,  
  5.     {ok, State}.  
  6.   
  7. ...  
  8.   
  9. terminate(shutdown, State) ->  
  10.     ..code for cleaning up here..  
  11.     ok.  



2.6.2 Stand-Alone Gen_Servers

If the gen_server is not part of a supervision tree, a stop function may be useful, for example:

java 代码
 
  1. ...  
  2. export([stop/0]).  
  3. ...  
  4.   
  5. stop() ->  
  6.     gen_server:cast(ch3, stop).  
  7. ...  
  8.   
  9. handle_cast(stop, State) ->  
  10.     {stop, normal, State};  
  11. handle_cast({free, Ch}, State) ->  
  12.     ....  
  13.   
  14. ...  
  15.   
  16. terminate(normal, State) ->  
  17.     ok.  


The callback function handling the stop request returns a tuple {stop, normal, State1}, where normal specifies that it is a normal termination and State1 is a new value for the state of the gen_server. This will cause the gen_server to call terminate(normal,State1) and then terminate gracefully.

2.7 Handling Other Messages

If the gen_server should be able to receive other messages than requests, the callback function handle_info(Info, State) must be implemented to handle them. Examples of other messages are exit messages, if the gen_server is linked to other processes (than the supervisor) and trapping exit signals.

java 代码
  1. handle_info({'EXIT', Pid, Reason}, State) ->  
  2.     ..code to handle exits here..  
  3.     {noreply, State1}.  


  • 描述: client_server
  • 大小: 2.1 KB
分享到:
评论

相关推荐

    Erlang OTP设计原理文档 中文版本

    Erlang OTP(Open Telephony Platform)是Erlang编程语言的一个核心部分,它提供了...通过深入理解这些文档和概念,开发者能够构建出符合OTP原则的、高度可靠的Erlang系统,有效地处理并发、故障恢复和系统扩展性问题。

    erlang 聊天室

    1. **服务器端代码**:包含gen_server行为的实现,用于处理连接、消息传递和状态管理。 2. **客户端代码**:可能使用gen_tcp来建立与服务器的连接,并提供用户界面,让用户输入和显示聊天内容。 3. **通信协议**:...

    使用OTP原理构建一个非阻塞的TCP服务器

    通过遵循这些步骤和最佳实践,我们可以构建一个符合OTP原则的非阻塞TCP服务器,它具有高可用性、容错能力和良好的可扩展性。对于不熟悉OTP的开发者,建议阅读相关的教程和文档,以深入理解其设计理念和用法。

    Erlang OTP并发编程实战 附书源码

    它包含了一组设计原则和库模块,如 supervision trees(监督树)、gen_server行为、gen_event行为等,为开发者提供了一种结构化的方式来处理并发和错误恢复。 1. **Supervision Trees**:OTP的核心概念之一是监督树...

    OTP Design Principles

    ### OTP设计原则详解 #### 概览 OTP(Open Telecom Platform)是Erlang/OTP框架的核心组成部分之一,它提供了一套成熟的、可扩展的、容错的应用程序设计模式。OTP设计原则指导开发者如何构建稳定可靠的分布式系统...

    Erlang_OTP_设计原理(含目录).pdf

    文档详细讲解了Gen_Server行为模式,其中包括如何启动和停止Gen_Server,处理同步(Call)和异步(Cast)调用,以及在监督树中的集成。Gen_Fsm行为介绍了有限状态机的基本原理以及如何使用Gen_Fsm来管理状态变化和...

    erlang_otp_src_17.3.tar.gz

    7. **行为模块**:如gen_server、gen_event、gen_fsm等,是OTP设计模式的具体实现,简化了编写服务器、事件处理器和有限状态机的代码。 关于压缩包内的"otp_src_17.3",这是Erlang OTP 17.3版本的源代码目录。为了...

    gen-batch-server:用于Erlang和Elixir的通用批处理服务器

    gen_server行为是Erlang OTP设计模式之一,用于创建有状态的服务进程,而Elixir的GenServer是Erlang gen_server的封装,提供了更友好的Elixir语法和API。 批处理服务器的主要功能包括: 1. **任务调度**:gen-...

    Erlang_OTP_设计原理 中文版

    例如Gen_Server、Gen_Fsm、Gen_Event和Supervisor等。每个行为模式都有其通用部分和特定部分。通用部分由Erlang/OTP库提供,开发者只需要专注于实现特定部分,即回调模块,以及根据需要导出特定的回调函数。 3. ...

    Erlang-OTP-API 离线查询英文全手册

    10. **系统架构**:OTP鼓励使用微服务和模块化的设计,手册将指导如何组织和构建符合OTP原则的系统架构。 这份离线手册的R14B03版本可能相对较旧,但依然具有很高的参考价值,尤其是对于初学者和在旧系统上工作的...

    otp-OTP-20.0.tar.gz

    5. **Supervisor和gen_server**:OTP的监控和行为模式,帮助构建有弹性的系统,能够自动检测和恢复错误。 6. **Distributed OTP**:支持Erlang节点间的通信和分布式应用,确保即使在网络故障或节点失败后,系统也能...

    Erlang OTP 设计原理 - 中文版

    例如,Gen_Server和Gen_Fsm都是Erlang OTP提供的行为模式,它们定义了处理消息的基本结构,并要求开发者实现与具体逻辑相关的回调函数。 应用(Application)在Erlang/OTP中是一个封装了代码、模块、资源文件和配置...

    erlang的翻译文档

    - **Gen_Server 行为**:文档中未给出具体细节,但通常涉及服务器进程的设计和实现。 - **Gen_Fsm 行为** - **有限状态机**:介绍了如何使用Gen_Fsm实现状态机逻辑。 - **示例**:提供了Gen_Fsm的具体用法示例。 ...

    Erlang/OTP 中文手册(R11B)

    - **行为(Behaviours)**:如gen_server、gen_event和gen_fsm等,定义了标准的服务器、事件管理和有限状态机的行为模式,为编写可靠服务提供模板。 - **应用(Applications)**:Erlang程序组织成应用,每个应用有...

    Erlang中文手册

    #### 六、OTP设计原则 **2.1 概述** - **OTP (Open Telecom Platform)**: Erlang的一个高级框架,提供了构建可扩展、容错系统的一套设计模式和工具集。 - **组件**: - 监督树 (Supervision Trees): 管理进程的...

    Erlang中文手册.pdf

    ### OTP设计原则 #### 2.1 概述 - **2.1.1 监督树**:介绍了Erlang OTP框架中的监督树概念。 - **2.1.2 Behaviour**:行为模块是用于编写特定类型进程的模板。 - **2.1.3 应用**:解释如何将模块和行为组合成应用...

    Erlang入门:构建application练习5(监督树)

    2. **模块(`.erl`)**:实际实现功能的代码,可以是普通的函数模块,也可以是行为模块(如gen_server,gen_event等)。 3. **启动脚本(`.boot`)**:指定启动应用时的初始状态,包括启动哪些进程及其顺序。 4. *...

    timekeeper:ErlangOTP的游戏时钟应用程序

    1. **gen_server行为模块**:Timekeeper可能实现了一个gen_server行为,这是一个标准的Erlang OTP服务器模板,用于处理客户端的请求并保持内部状态。gen_server提供了一种结构化的方式来处理异步请求,更新状态,并...

Global site tag (gtag.js) - Google Analytics