1.通用事件处理
如果在编程的时候发生了一件值得关注的事,就会发送一个event消息给某个注册进程。
发送消息后我们不知道(也不关心)它的命运。只是完成自己的任务,告诉其他人有什么事 发生。
接收事件消息的进程,被称为事件处理器。
最简单的事件处理器就是一 个“什么都不做”的处理器。当它收到一个{event, X}消息时不会对它做任何处理,只会把它丢弃。
%% 制作一个“什么都不干”的事件处理器Name(一个原子)。这样消息就有地方发送了。
make(Name) ->
register(Name, spawn(fun() -> my_handler(fun no_op/1) end)).
%% 给名为Name的事件处理器添加一个处理函数Fun。这样当事件X发生时,事件处理器就会执行Fun(X)。
add_handler(Name, Fun) -> Name ! {add, Fun}.
%% 发送消息X到名为Name的事件处理器。
event(Name, X) -> Name ! {event, X}.
my_handler(Fun) ->
receive
{add, Fun1} ->
my_handler(Fun1);
{event, Any} ->
(catch Fun(Any)),
my_handler(Fun)
end.
no_op(_) -> void.
运行结果如下
要让事件处理器能做点什么,必须编写一个回调模块并把它安装到事件处理器里。
add_event_handler() ->
event_handler:add_handler(errors, fun controller/1).
controller(too_hot) ->
io:format("Turn off the motor~n");
controller(X) ->
io:format("~w ignored event: ~p~n", [?MODULE, X]).
现在当我们发送消息给处理器时,函数motor_controller:controller/1会处理这些消 息。
这里的要点在于事件处理器提供了一种架构,让我们可以安装自定义的处理器。
2.错误记录器
OTP系统自带一个可定制的错误记录器。可以从三个角度看待错误记录器:
1.程序员视角关心程序员为了记录错误而在代码里中做的函数调用;
2.配置视角关心错误记录器在何处以及如何保存数据;
3.报告视角关心对已发生错误的分析。
错误记录器
有多种方式可用来配置错误记录器。
1.可以让Erlang shell显示所有错误(如果没有特别设置的话就是默认值);
2.可以把shell里报告的所有错误写入一个格式化文本文件。
3.还可以创建一个滚动日志(rotating log)。可以把滚动日志看作是一个大型循环缓冲区,内含错误记录器生成的消息。新消息进来后会被附加到日志的末尾,如果日志满了,最早的条目就会被删除。
在启动Erlang时可以给系统提供一个启动参数。
$ erl -boot start_clean
它会创建一个适合进行程序开发的环境,只提供一种简单的错误记录形式。(不带启动参
数的erl命令就等于erl -boot start_clean。)
$ erl -boot start_sasl
它会创建一个适合运行生产系统的环境。系统架构支持库(System Architecture Support
Libraries,简称SASL)将负责错误记录和过载保护等工作
错误记录器会生成多种报告类型:
1.监控器报告 这些报告会在OTP监控器启动或停止被监控进程时生成。
2.进度报告 这些报告会在OTP监控器启动或停止时生成。
3.崩溃报告 如果某个被OTP行为启动的进程因为normal或shutdown以外的原因终止,这些报告就会生成。 这三种报告都是自动生成的。