erlang的三驾马车proc_lib,gen,sys
1.为什么推荐使用proc_lib?
erlang:spawn
构建的process在运行失败的时候没有crash_report
但是proc_lib:spawn
构建的process有
在每个进程字典中都保存了$ancestors
和$initial_call
$ancestors
保存了进程的祖先格式:[Father, GrandFather...]
$initial_call
保存了调用点MFA
proc_lib既是erlang底层函数的简单封装,而且额外增加了process信息,详细记录了出错原因
2.gen 的使用技巧
2.1.定义了proc的name规则(whereis,register_name,unregister)
相关回调(callback)
whereis_name:
local -> erlang:whereis(Name)
global -> global:whereis_name(Name)
via -> Mod:whereis_name(Name)
unregister:
local -> erlang:unregister(Name)
global -> global:unregister_name(Name)
via -> Mod:unregister_name(Name)
register:
local -> erlang:register(Name, self())
global -> global:register_name(Name, self())
via -> Module:register_name(Name, self())
这里除了系统定义的本地名字规则和全局名字规则之外,开发者还可以自己定义(via)一个名字规则,比如可以使用redis,mysql等来做名字到pid的映射,方便定制
2.2. gen是gen_server,gen_event,gen_statem和proc_lib的桥接
gen抽象出了GenMod:init_it
的行为,让gen_server,gen_event等有统一的初始化回调,并且桥接了proc_lib,使得gen_server等有完成的crash日志
2.3. gen抽象了call,stop,reply行为
在执行call,stop操作的时候,统一进行了monitor行为,捕获了对象Down的消息
3. sys对proc更多的掌控
3.1 suspend,resume
suspend和resume是proc的运行时hook,主要作用是挂起和继续
可以用在热更上,入sasl的relup功能就依赖这两个hook
如果想要了解更多细节,请参阅release_handler.erl
实现方式:
向目标进程发送消息{system, From, suspend}
proc便会一直Loop,直到收到 `` {system, From, Req}消息,忽略其他的消息
从外面看来这个时候的proc就像是在挂起一样
3.2 get_state,replace_state
这两个函数主要的作用是得到,设置proc的状态(我习惯上叫Actor的状态)
前者在调试代码的时候非常有用,可以每时每刻看到gen_server的状态,是否符合自己的预期
实现方式:
向目标进程发送消息{system, From, get_state}
回调函数:Mod:system_get_state(Misc)
,便可以获取proc的state,完全符合状态和代码完全隔离的效果
向目标进程发送消息{system, From, {replace_state, StateFun}}
回调函数:{ok, State, NMisc} = Mod:system_replace_state(StateFun, Misc)
StateFunNState = StateFun(State)
就是将一个状态转化为另一个状态
3.3 log,trace,trace,statistics,log_to_file
这几个函数主要是对proc近期收到消息的情况的一些概况,近期收到几条消息(statistics),这些消息内容是什么(log)?还可以将这些消息内容写到文件里面(log_to_file)
实现方式:
这几个函数都在操控gen_server的options的 {debug, L}参数中
主要包含
{debug,true|false}
{log,N}
{log_to_file, false}
{log_to_file, Fd}
来实现上面的需求,具体代码请参考sys.erl
总结
三驾马车能让人对erlang程序有更深的理解。对如何规范的设计系统以及每一个Actor有很大的帮助,抽象出更通用的业务逻辑
网友评论