Erlang 细节记录

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Erlang 细节记录相关的知识,希望对你有一定的参考价值。

参考技术A 善用Erlang的Attributes属性,比如RabbitMQ中的-rabbit_boot_step用来记录该模块启动的前置条件和后置条件。
使用Module:module_info(attributes)进行获取。

 当遇到消息会和(rendezvous)问题时,可以在call中借助gen_server:reply(From,Reply)进行灵活的答复消息处理,并且可以将准备的数据暂存于state中。
(来自《高伸缩性系统 Erlang/OTP大型分布式 容错设计》83页)

在gen_server的init函数中失败了,返回stop,Reason并不会调用terminate(),而是start_link()会返回error,Reason。
(来自《高伸缩性系统 Erlang/OTP大型分布式 容错设计》85页)

gen_server出现运行时错误而导致进程终止时,如果gen_server时设定为捕捉退出信号的(process_flag(trap_exit,true)),则terminate/2会被调用,否则会直接退出。
(来自《高伸缩性系统 Erlang/OTP大型分布式 容错设计》86页)

gen_server:call内置了5秒的超时时间,如果client 5s内没收到回应就会触发一个异常。如果client要捕获这个异常,必须要考虑到server处理完后返回的消息!
(来自《高伸缩性系统 Erlang/OTP大型分布式 容错设计》87页)

即使client进程有很长的消息队列,但是receive分局匹配回应时并不需要遍历整个消息队列。
(这句话有点没理解)
(来自《高伸缩性系统 Erlang/OTP大型分布式 容错设计》88页)

gen_server的返回值最后一个参数可以加上超时值,noreply,State,?TIMEOUT,如果加了,那么在指定时间没有收到消息,就会发送timeout消息,在handle_info(timeout,State)中处理。

接上一条。当超时值设置为hibernate时,会降低server的内存消耗进入到等待状态中,并且会丢弃调用栈、进行一次完成的垃圾回收、把一切归置到一块连续的堆中。
但是!作者严重警告需要非常谨慎的使用该参数,因为休眠与唤醒都需要消耗资源!
(来自《高伸缩性系统 Erlang/OTP大型分布式 容错设计》92页)

gen_server的NameScope可以是via,Module,Name、local,Name、global,Name。
想把请求广播给一个节点集群内的所有server时,可以使用gen_server:multi_call/3或者abcast/3。call会返回结果,cast不会。

fun函数也能实现模式匹配。
fun
(c1,Data) ->
    code1;
(c2,Data) ->
    code2
end.

sys模块可以统计很多的数据,篇幅较多,后续有必要再补充。

erlang 20.0开始,gen_fsm被设计成更好的gen_statem。

修改 Erlang 记录 [重复]

【中文标题】修改 Erlang 记录 [重复]【英文标题】:Modifying an Erlang Record [duplicate] 【发布时间】:2015-08-02 08:57:40 【问题描述】:

我知道 Erlang 中的记录一旦设置就无法更改。我正在尝试使用记录来增加价值。

add_new_num() ->
    Number = random:uniform(6),
    STR = #addervalue = 7,
    New = add(STR, Number).         

add(#addervalue =V = Adder, Value) ->
    Adder#addervalue = V + Value.

运行add_new_num() 时,我总是会得到7 + Number。这不是我想要的。我想让它做以下事情。

add_new_num() -> 7 + Number = Val
add_new_num() -> Val + Number = Val2
add_new_num() -> Val2 + Number = Val3
...

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

有多种方法可以做到这一点。想想你想把值存储在哪里:Erlang 没有像 C 那样的“静态变量”,所以函数本身无法记住值。

您可以将当前记录作为参数传递给add_new_num,并从其返回值中获取更新的记录。你可以保持一个进程运行,并发送消息来查询它的当前值并要求它增加值。或者您可以将值存储在ETS table,甚至Mnesia。

【讨论】:

我将如何从返回值@legoscia 更新记录

以上是关于Erlang 细节记录的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Erlang 中的模式匹配记录会抛出错误

修改 Erlang 记录 [重复]

Erlang-如何在没有记录的情况下使用 Mnesia

Erlang和运行时记录限制

将erlang记录发送到c程序

RabbitMQ 部署记录