【问题标题】:What happens in Erlang if return receipt never arrives?如果回执永远不会到达,Erlang 会发生什么?
【发布时间】:2013-07-05 20:35:58
【问题描述】:

我只是碰巧读了 Joe Armstrong 的论文,对 Erlang 没有太多的先验知识。我想知道如果某些消息的送达收据从未到达会发生什么。发送演员做什么?它会再次发送消息吗?当接收方再次收到相同的消息时,这可能会使接收方演员感到困惑。它必须能够告诉它没有收到它的收据,因此第二条消息是无效的。

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

感谢您的任何回答, 奥利弗

【问题讨论】:

    标签: erlang fault-tolerance


    【解决方案1】:

    在 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,
        ...
    

    只需很少的工作,甚至可以将消息传递的调查委托给一个新进程 - 不阻塞检查 - 并使用链接进程,如果达到超时,则强制发送方崩溃。

    【讨论】:

    • 感谢您分享您的知识。你知道是否有一些文档/书籍提到了如何处理这类事情的最佳实践?
    • 我最喜欢的信息来源是learnyousomeerlang.com,当你知道你在寻找什么时,官方文档是值得获取的信息。你还有一些书:Francesco Cesarini 和 Simon Thompson 的 Programming erlang; Martin Logan、Eric Meritt 和 Richard Carlsson 的 Erlang 和 OTP。最后,我还喜欢一小部分截屏视频——因为渐进式方法(凯文·史密斯:实用截屏视频)
    猜你喜欢
    • 2017-05-25
    • 2011-03-01
    • 2016-01-22
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 2018-04-08
    • 1970-01-01
    相关资源
    最近更新 更多