全部博文(921)
分类: Python/Ruby
2012-10-22 12:00:10
在OTP中,事件管理器是一个事件可以发送到的命名对象,一个事件可以是一个错误、一个警告、或者一些要写入日志的信息
在事件管理器中,有0个、一个或者多个事件处理器被安装,当事件管理器被一个事件通知时,这个事件将被安装在事件管理器中的事件处理器处理,
事件管理器用一个进程实现,事件处理器用回调模块实现。事件管理器本质上维护一个{Module, State}列表,每一个Module为一个事件处理器,而State为事件处理器的内部状态。
2. 例子事件处理器的回调模块把错误信息写入终端
事件处理器的回调模块把错误信息写入文件
调用
启动管理器,这个函数生成并连接到一个新进程,参数{local, error_man}指定名称,在这个例子中,事件管理器被局部注册为error_man
假如忽略名称,那么事件管理器不会被注册,它的PID将被使用。名称也可以是这种形式{global, Name},这样,事件管理器的名称是用global:register_name/2注册的。
假如事件管理器是监控树的一部分,那么gen_event:start_link必须被使用,也就是被监控树启动,而gen_event:start启动单独的事件管理器,也就是事件管理器不是监控树的一部分。
4. 添加事件处理器下面的例子显示怎样启动一个事件管理器和添加一个事件处理器
gen_event:add_handler(error_man, terminal_logger, [])为error_man添加处理器terminal_logger,事件管理器调用terminal_logger:init([])这个回调函数, []是参数,init要返回一个{ok, State},State是事件处理器的内部状态
这里,init不需要任何输入参数,对于terminal_logger,也没使用内部状态,对于file_logger,内部状态保存了打开的文件描述符
error_man是事件管理器的名称,no_reply是事件,事件作为消息发送给事件管理器,当事件被收到时,事件管理器为每个安装的事件处理器按安装次序调用handle_event(Event, State),这个函数期待返回{ok, State1},State1是事件处理器的新状态。
在terminal_logger中
在file_logger中
gen_event:delete_handler(error_man, terminal_logger, []),这个函数向事件管理器error_man发送了一个消息,告诉他删除terminal_logger这个事件处理器,事件管理器将调用terminal_logger:terminate([], State),参数[]是delete_handler的第三个参数,terminate以init相反的方向调用,以完成清理工作,返回值被忽略。
在terminal_logger中,没有清理动作
当事件管理器被停止,它给每个注册的事件处理器调用terminate/2的机会,就好像事件处理器被删除一样。如果事件管理器是监控树的一部分,不需要显示的停止事件管理器。当事件管理器作为单独进程使用时,则调用gen_event:stop(error_man).
转载自: