我正在查看有关无类型演员(http://doc.akka.io/docs/akka/2.3.2/java/untyped-actors.html)
的Akka Java文档我实际上想要完成诸如以下的事情:
为我希望在onReceive()方法中收到的任何特定邮件设置超时。例如:
public void onReceive(Object message) throws Exception {
if (message.equals("start")) {
child.tell("fetch something for me!", getSelf());
}
if (message.equals("child's response")) {
// handle a response from a child here,
// but timeout within some timeframe if I don't get a
// response quick enough.
// use this here? getContext().setReceiveTimeout(Duration.create("1 second"));
}
}
我知道你可以使用Patterns.ask(actor,message,timeout),它返回一个未来。如果未在指定的超时参数内发回响应,则失败。
我不想在这里使用期货。我不明白setReceiveTimeout方法的用法。我如何通过纯粹使用actor.tell来实现这一目标?
答案 0 :(得分:7)
您应该在对另一个演员执行tell
后立即设置接收超时。一旦你这样做,时钟基本上开始滴答作响。如果此actor在该时间范围内未收到任何邮件,则会在邮箱中放入ReceiveTimeout
消息,表明您未及时收到回复。为此考虑的代码的更新版本如下所示:
public void onReceive(Object message) throws Exception {
if (message.equals("start")) {
child.tell("fetch something for me!", getSelf());
getContext().setReceiveTimeout(Duration.create("1 second"));
}
else if (message.equals("child's response")) {
getContext().setReceiveTimeout(Duration.Undefined()); //turn off receive timeout
// handle a response from a child here
}
else if (message instanceof ReceiveTimeout) {
getContext().setReceiveTimeout(Duration.Undefined()); //turn off receive timeout
// handle situation where I did not get a response in time
}
}
您会注意到,无论是实际响应还是接收超时,我都会关闭tell
之后设置的接收超时。接收超时正在重复;如果我没有明确地将其关闭,它将继续每隔一段时间发送ReceiveTimeout
条消息(根据我设置接收超时时间间隔的内容)。
请务必记住,接收超时功能是消息特定的。也就是说,如果我收到任何消息到我的邮箱,它会被跳过一段时间;不只是我想要的那个。因此,如果某个其他演员向我发送了另一个完全不同的消息,它将跳过该间隔的接收超时。如果这不是一个问题,那么就不用担心了。但是,如果响应之外的其他消息可能到达,则需要相应地处理,根据自最初设置之后经过的时间(可能通过Deadline
实例)重置原始接收超时。