我刚刚读过Joe Armstrong的论文,并且对Erlang没有太多的先验知识。我想知道如果某个消息的送货收据永远不会到达会发生什么。派遣演员做什么?它又发送消息了吗?当另一次收到相同的消息时,这可能会使收件人参与者感到困惑。它必须能够告知未收到收据,因此第二条消息无效。
这种问题总是让我远离消息传递不是交易的解决方案。我想我知道答案:派出演员告诉其监督演员,如果在合理的时间内没有获得收据,导致主管采取某些行动(比如重新启动演出的演员或其他东西),则必须出错。它是否正确?我认为没有其他解决方案不会导致无限可能的无限消息发送。
感谢您的回答, 奥利弗
答案 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,
...
只需要很少的工作,甚至可以将消息传递调查委托给新进程 - 不阻止检查 - 并使用链接进程,如果达到超时,则强制发送方崩溃。