如果退货收据从未到达,在Erlang会发生什么?

如果退货收据从未到达,在Erlang会发生什么?,erlang,fault-tolerance,Erlang,Fault Tolerance,我只是碰巧读了乔·阿姆斯特朗的论文,对二郎没有多少先验知识。我想知道如果某封邮件的送达回执一直没有收到会发生什么。派遣演员做什么?它会在另一时间发送消息吗?这可能会使收件人参与者在另一次收到相同的消息时感到困惑。它必须能够告知未收到其收据,因此第二条消息无效 这种问题总是让我远离那些消息传递不是事务性的解决方案。我想我知道答案:发送参与者告诉其主管参与者,如果没有在合理的时间内获得收据,导致主管采取一些行动(如重新启动已开票的参与者或其他事情),那么一定是出了问题。这是正确的吗?我认为没有其他解

我只是碰巧读了乔·阿姆斯特朗的论文,对二郎没有多少先验知识。我想知道如果某封邮件的送达回执一直没有收到会发生什么。派遣演员做什么?它会在另一时间发送消息吗?这可能会使收件人参与者在另一次收到相同的消息时感到困惑。它必须能够告知未收到其收据,因此第二条消息无效

这种问题总是让我远离那些消息传递不是事务性的解决方案。我想我知道答案:发送参与者告诉其主管参与者,如果没有在合理的时间内获得收据,导致主管采取一些行动(如重新启动已开票的参与者或其他事情),那么一定是出了问题。这是正确的吗?我认为没有其他解决方案不会导致理论上可能的无限消息发送

谢谢你的回答,
Oliver

在Erlang中,消息的发送者通常在发送消息后立即忘记它,并继续其工作。如果应用程序需要确认消息接收,则必须构建自己的协议(或使用现有协议)。这有很多很好的理由

一是大多数情况下,没有必要进行握手。消息被忽略的更高风险是接收过程不再存在,或者同时死亡,在这种情况下,发送者很少有机会做一些有趣的事情

此外,握手是一种阻塞动作,因此会影响性能,并有死锁的风险

确认也应该是一条消息,但这条消息不应该被确认,否则您将创建一个永无止境的消息循环。只有应用程序才能知道该做什么(例如使用带确认或不带确认的发送),编写这种函数(或使用实现它的行为)非常容易。例如:

send_with_ack(To,Mess,TimeOut,Ack) ->
    Ref = make_ref(),
    To ! {Mess,self(),Ref},
    receive
        {Ack,Ref} -> Ack
    after Timeout ->
        {error,timeout}
    end.



receiving_process() ->
    ...
     receive
        {Pattern_matching_Mess,From,Ref} ->
            do_something(),
            From ! {Ack,Ref}, %% Ack for this kind of message is known by the receiver
            do_somethingelse();
        Mess1 -> do_otherthing()
    end,
    ...

只需很少的工作,甚至可以将邮件传递调查委托给一个新流程(而不是阻止检查),并使用链接流程,在超时时强制发件人崩溃。

感谢分享您的知识。你知道是否有一些文档/书籍提到了如何处理这类事情的最佳实践?我最喜欢的信息来源是,当你知道你在寻找什么时,官方文档是值得获得信息的。你也有一些书:弗朗西斯科·塞萨里尼和西蒙·汤普森的《编程erlang》;马丁·洛根、埃里克·梅里特和理查德·卡尔森在《Erlang和OTP的行动》。最后,我还喜欢一系列小的屏幕广播——因为渐进式的方法(凯文·史密斯:实用的屏幕广播)