如果发送者演员已经离开,响应会发生什么?

4
考虑以下例子。一个名为hello_world actor的Actor向mirror actor发送"hello"字符串,然后立即终止。那么从mirror actor返回的响应world会发生什么?被忽略了吗?还是留在hello_world actor的邮箱里?镜子能否知道它的响应丢失了?
behavior mirror(event_based_actor* self)
{
    return { [=](std::string s){ return "world"; } };
}
void hello_world(event_based_actor* self, const actor& theMirror)
{
    self->send(theMirror, "hello");
}
1个回答

5
考虑以下示例。一个hello_world actor向mirror actor发送“hello”字符串,然后立即终止。镜像演员返回的响应world会发生什么?被忽略了吗?留在hello_world actor邮箱中?
假设hello_world已经终止。当CAF运行时下一次将控制权转移给mirror时,语句“return "world"”将尝试向发送方发送回复。由于发送方不存在,运行时程序简单地丢弃该消息。
镜像是否知道其响应已丢失?
长话短说:如果您需要消息传递保证,则必须在其上实现自己的确认协议。
详细答案:通过监视actor,可以挂钩其终止。最终,这只是将特定系统消息排队到监视器演员的邮箱中。假设单跳场景下没有消息重排序,hello_world将发送一条消息,终止,然后运行时程序将向所有监视hello_world的演员发送DOWN消息。因此,镜像邮箱中首先包含字符串,然后是DOWN消息。这意味着只有在尝试发送消息之后,mirror才能检测到失败。
有一个例外:如果将mirror作为具有优先级感知的actor生成,则可以基于其优先级处理消息。将其视为每个actor的两个单独的邮箱。在CAF中,所有系统消息都具有高优先级,这意味着存在一种情况,您可能能够在回复之前检测到故障,但仅当运行时程序在mirror的邮箱中已经存在两个消息时,才可以进行控制转移。如果DOWN消息被延迟,并且运行时程序将控制权转移给只有字符串消息的邮箱,则则不能检测到失败。
也就是说,actor可以随时发生故障,而运行时程序只能提供接近实时的故障传播。因此,您的设计必须对此类故障具有弹性,这意味着您必须为可靠的消息传递自己编写确认机制。

为了对这个答案增加更多细节:当使用sync_send(在CAF 0.15中将被request替换)时,如果接收者不再存在,运行时会生成错误消息。然而,这并没有实现三次握手,即hello_world可以检测到mirror是否正确响应,但mirror无法跟踪响应消息的情况(除非您像@mavam已经说明的那样在顶部实现此操作)。 - neverlord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接