如果回复收据永远不会到达,Erlang会发生什么?

时间:2013-07-05 06:58:44

标签: erlang fault-tolerance

我刚刚读过Joe Armstrong的论文,并且对Erlang没有太多的先验知识。我想知道如果某个消息的送货收据永远不会到达会发生什么。派遣演员做什么?它又发送消息了吗?当另一次收到相同的消息时,这可能会使收件人参与者感到困惑。它必须能够告知未收到收据,因此第二条消息无效。

这种问题总是让我远离消息传递不是交易的解决方案。我想我知道答案:派出演员告诉其监督演员,如果在合理的时间内没有获得收据,导致主管采取某些行动(比如重新启动演出的演员或其他东西),则必须出错。它是否正确?我认为没有其他解决方案不会导致无限可能的无限消息发送。

感谢您的回答, 奥利弗

1 个答案:

答案 0 :(得分:2)

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

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