erlang的“监视器”给出了什么保证?

时间:2014-06-19 18:35:16

标签: erlang message-passing

在阅读ERTS用户指南时,我发现了这一部分:

  

给出的唯一信号排序保证如下。如果实体将多个信号发送到同一目的地   实体,订单将被保留。也就是说,如果A发送信号S1到B,然后将信号S2发送到B,则S1为   保证不会在S2之后到达。

在进行进一步的研究谷歌搜索时,我也发生过这种情况:

Erlang参考手册,13.5:

  

邮件发送是异步且安全的,只要收件人存在,邮件就可以保证最终到达收件人。

这看起来很模糊,我想知道在以下情况下我可以依赖什么保证:

 A,B are processes on two different nodes.
 Assume A does not crash and B was a valid node at some point.
 A and B monitor each other.
 A sends messages M1,M2,M3 to B

在上面的场景中,B是否可能接收到M1,M3(M2被丢弃),      没有在A?

收到任何'DOWN'/'EXIT'/心跳超时

2 个答案:

答案 0 :(得分:2)

除订购保证外,没有其他保证。请注意,默认情况下,您甚至不知道发件人是谁,除非发件人在邮件中对此进行编码。

你的例子可能会发生:

  • A发送M1和M2
  • B收到M1
  • B所在的节点断开连接
  • B所在的节点再次出现
  • A发送M3到B
  • B收到M3

在此方案中,M2可能会丢失在网络链接上。这种情况极不可能发生,但可以发生。通常的诀窍是有某种这种错误的概念。通过超时触发器,或通过监控节点或Pid作为消息的接收者。

更新方案:

在更新的场景中,如果我正确读取它,那么A会在某个时刻获得'DOWN'样式的消息,同样,它会收到一条消息,告诉您该节点再次启动,如果您监视节点。

尽管如此,如果可能的话,使用幂等协议可以更好地建模。

答案 1 :(得分:0)

通过erlang mailing-listacademic faq阅读,似乎ERTS实施提供了一些保证,但我无法确定它们是否以某种语言保证/规范水平。

如果您认为TCP是“可靠的”,那么当前的实施保证了 给定A,B是不同节点(&主机)上的进程和A监视器B,A发送给B,假设A没有崩溃,两个节点之间的任何消息传递失败*或B上的主机/节点/进程失败导致A收到'DOWN'消息(或者在链接的情况下为'EXIT')。 [见12]

*根据我在mailing-list thread上看到的内容,此属性几乎完全基于使用TCP的事实,因此“消息传递失败”意味着TCP决定发生故障的任何情况/连接需要关闭。

academic faq谈论这个问题,因为它也是一种语言/规范级别的保证,但是我还没有找到任何支持它的东西。