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

OTP设计原则:Gen_Event 行为

UP 
阅读更多

4 Gen_Event 行为


这一章应该与gen_event(3)结合起来看,gen_event(3)对所有接口函数和回调函数都有详细描述. 

4.1 事件处理原则

在OTP中, an event manager is a named object to which events can be sent. An event could be, for example, an error, an alarm or some information that should be logged.

In the event manager, zero, one or several event handlers are installed. When the event manager is notified about an event, the event will be processed by all the installed event handlers. For example, an event manager for handling errors can by default have a handler installed which writes error messages to the terminal. If the error messages during a certain period should be saved to a file as well, the user adds another event handler which does this. When logging to file is no longer necessary, this event handler is deleted.

An event manager is implemented as a process and each event handler is implemented as a callback module.

The event manager essentially maintains a list of {Module, State} pairs, where each Module is an event handler, and State the internal state of that event handler.

4.2 Example

The callback module for the event handler writing error messages to the terminal could look like:

java 代码
 
  1. -module(terminal_logger).  
  2. -behaviour(gen_event).  
  3.   
  4. -export([init/1, handle_event/2, terminate/2]).  
  5.   
  6. init(_Args) ->  
  7.     {ok, []}.  
  8.   
  9. handle_event(ErrorMsg, State) ->  
  10.     io:format("***Error*** ~p~n", [ErrorMsg]),  
  11.     {ok, State}.  
  12.   
  13. terminate(_Args, _State) ->  
  14.     ok.  


The callback module for the event handler writing error messages to a file could look like:

java 代码
 
  1. -module(file_logger).  
  2. -behaviour(gen_event).  
  3.   
  4. -export([init/1, handle_event/2, terminate/2]).  
  5.   
  6. init(File) ->  
  7.     {ok, Fd} = file:open(File, read),  
  8.     {ok, Fd}.  
  9.   
  10. handle_event(ErrorMsg, Fd) ->  
  11.     io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),  
  12.     {ok, Fd}.  
  13.   
  14. terminate(_Args, Fd) ->  
  15.     file:close(Fd).  
  16.       

The code is explained in the next sections.

4.3 Starting an Event Manager

To start an event manager for handling errors, as described in the example above, call the following function:

java 代码
  1. gen_event:start_link({local, error_man})  


This function spawns and links to a new process, an event manager.

The argument, {local, error_man} specifies the name. In this case, the event manager will be locally registered as error_man.

If the name is omitted, the event manager is not registered. Instead its pid must be used. The name could also be given as {global, Name}, in which case the event manager is registered using global:register_name/2.

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

4.4 Adding an Event Handler

Here is an example using the shell on how to start an event manager and add an event handler to it:

1> gen_event:start({local, error_man}).
{ok,<0.31.0>}
2> gen_event:add_handler(error_man, terminal_logger, []).
ok

This function sends a message to the event manager registered as error_man, telling it to add the event handler terminal_logger. The event manager will call the callback function terminal_logger:init([]), where the argument [] is the third argument to add_handler. init is expected to return {ok, State}, where State is the internal state fo the event handler.

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


Here, init does not need any indata and ignores its argument. Also, for terminal_logger the internal state is not used. For file_logger, the internal state is used to save the open file descriptor.

java 代码
  1. init(_Args) ->  
  2.     {ok, Fd} = file:open(File, read),  
  3.     {ok, Fd}.  


4.5 Notifying About Events

3> gen_event:notify(error_man, no_reply).
***Error*** no_reply
ok

error_man is the name of the event manager and no_reply is the event.

The event is made into a message and sent to the event manager. When the event is received, the event manager calls handle_event(Event, State) for each installed event handler, in the same order as they were added. The function is expected to return a tuple {ok, State1}, where State1 is a new value for the state of the event handler.

In terminal_logger:

java 代码
 
  1. handle_event(ErrorMsg, State) ->  
  2.     io:format("***Error*** ~p~n", [ErrorMsg]),  
  3.     {ok, State}.  
  4.       
  5.   
  6. In file_logger:  
  7.   
  8. handle_event(ErrorMsg, Fd) ->  
  9.     io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),  
  10.     {ok, Fd}.  

    

4.6 Deleting an Event Handler

4> gen_event:delete_handler(error_man, terminal_logger, []).
ok

This function sends a message to the event manager registered as error_man, telling it to delete the event handler terminal_logger. The event manager will call the callback function terminal_logger:terminate([], State), where the argument [] is the third argument to delete_handler. terminate should be the opposite of init and do any necessary cleaning up. Its return value is ignored.

For terminal_logger, no cleaning up is necessary:

  
java 代码
  1. terminate(_Args, Fd) ->  
  2.     file:close(Fd).  


For file_logger, the file descriptor opened in init needs to be closed:

java 代码
  1. terminate(_Args, Fd) ->  
  2.     file:close(Fd).  


4.7 Stopping

When an event manager is stopped, it will give each of the installed event handlers the chance to clean up by calling terminate/2, the same way as when deleting a handler.

4.7.1 In a Supervision Tree

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

4.7.2 Stand-Alone Event Managers

An event manager can also be stopped by calling:

> gen_event:stop(error_man).
ok

分享到:
评论

相关推荐

    otp_src_22.0_h.tar.gz

    OTP提供了几个设计良好的应用框架,如gen_server、gen_event、gen_fsm等,它们是基于行为模式的模块,简化了并发编程和状态管理。 5. **分布式功能** OTP支持跨节点的分布式计算,使得在多台机器上构建分布式系统...

    erlang OTP Design Principles之Gen中文

    Erlang OTP设计原则中的Gen_Fsm行为是一个关键的概念,用于构建健壮、可扩展的并发应用程序。Gen_Fsm,即通用有限状态机,是一种行为模式,它提供了一种结构化的方法来处理具有多种状态和事件的系统。本文将深入探讨...

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

    OTP设计原则着重于实现高度并发、容错性和高效能。下面将详细讨论Erlang OTP中的关键概念和相关知识点。 1. 监督树(Supervision Tree): 监督树是OTP设计的核心概念,它是一种组织Erlang进程的方式。每个节点都...

    otp_win64_23.1.exe|otp_win64_23.1.zip

    2. OTP框架:理解其模块化设计、行为(gen_server, gen_event等)、分布式应用和系统监控。 3. RabbitMQ基本概念:掌握消息队列的工作原理、交换器(exchanges)、队列(queues)、绑定(bindings)以及消费者...

    OTP Design Principles

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

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

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

    Erlang实战

    - 事件管理器负责调度事件处理器,可以通过 `gen_event:start/2` 或 `gen_event:start_link/2` 启动。 - 支持动态添加或移除事件处理器。 #### 四、开发实践要点 - **遵循标准目录结构**:采用标准的OTP目录结构,...

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

    Erlang OTP设计原理是一份深入探讨Erlang/OTP(Open Telecom Platform)框架中设计模式和组织代码原则的文档。Erlang OTP作为Erlang语言的中间件平台,提供了构建可扩展和容错系统的标准方法。 文档开篇就介绍了...

    otp_src_21.1.tar.gz

    1. **模块化设计**:OTP提供了各种预定义的进程行为模式(gen_server、gen_event、gen_fsm等),便于开发者创建符合特定模式的进程,提高了代码复用和可维护性。 2. **分布式计算**:Erlang OTP支持跨节点的进程...

    erlang_otp_src_17.3.tar.gz

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

    otp_src_R11B-5.tar.gz_OTP_erlang_otp-src-R11B_otp_s

    这些库包括Mnesia(分布式数据库)、Event Logger、公共接口定义语言(CIDL)以及行为模式如GenServer、GenEvent和Gen_fsm等。这些行为模式为开发者提供了构建状态管理、事件处理和分布式服务的标准结构,使得代码...

    erlang的翻译文档

    - **事件处理原则**:介绍了Gen_Event的行为模式。 - **示例**:提供了具体的Gen_Event用法示例。 - **启动事件管理器**:说明了如何启动事件管理器。 - **加入事件处理器**:讲解了如何添加事件处理器。 - **...

    Erlang_OTP_设计原理 中文版

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

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

    5. **行为模式(Behaviours)**:如`gen_server`、`gen_event`和`supervisor`等,这些是Erlang OTP设计模式的实现,它们为特定的系统角色提供了基础架构。例如,`gen_server`适用于处理服务请求,`gen_event`用于...

    ErlangOTP 21.3.zip

    OTP是Erlang生态系统的重要组成部分,提供了许多预先设计好的行为模式(如 gen_server、gen_event 和 supervisor),这些模式使得开发者能够快速构建出符合Erlang并发哲学的应用程序。 otp_src_21.3.tar是Erlang ...

    otp-OTP-19.3.zip

    3. **模块更新**:许多OTP库模块在19.3版本中得到了更新,例如`gen_server`、`gen_event`等行为模式,它们是构建Erlang应用程序的基础。这些更新通常涉及到性能提升、API调整或新功能的添加,以更好地适应不断发展的...

    erlang 参考手册 模块部分--自己翻译的中文版

    通过`-behaviour(Behaviour)`,模块可以声明为特定行为的回调模块,如OTP标准行为`gen_server`、`gen_fsm`、`gen_event`和`supervisor`。 4.2.3 记录(Record)定义 使用`-record(Record, Fields)`定义记录,记录...

    Erlang/OTP 中文手册(R11B)

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

    Erlang中文手册

    - **函数**: `gen_event:add_sup_handler/3`。 - **参数**: 事件管理器、处理器模块、处理器参数。 - **2.4.5 事件通知** - **定义**: 向事件处理器发送消息。 - **处理**: 在处理器模块中处理消息。 - **...

    Erlang中文手册.pdf

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

Global site tag (gtag.js) - Google Analytics