我已经使用Java在Akka框架中实现了一个应用程序。我有一个主要的actor通过使用'Ask'方法调用sub-actor并在60秒后超时,worker在收到来自Main Actor的消息后调用另一个java类方法。
现在的问题是,虽然我的主演员在60秒后超时仍然工作人员能够与java类方法交谈,然后该方法正在执行不需要的操作,因为主要演员无法接收响应虽然子actor由于超时而返回。
如果主要演员超时,我是否可以杀死工作人员或阻止其进一步处理?
我检查了RecieveTimeOut()
,context.stop()
和poisonpill等方法,但仍无用。
感谢您的支持
以下代码
public class MainActor extends UntypedActor {
ActorRef subActorRef;
final Timeout timeout = new Timeout(Duration.create(60, TimeUnit.SECONDS));
@Override
public void preStart() {
subActorRef = getContext().actorOf(
SpringExtProvider.get(actorSystem).props(
"SubActor"), "subActor");
}
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof BusinessRequestVO) {
BusinessRequestVO requestVo = (BusinessRequestVO) message;
ArrayList<Future<Object>> responseFutures = new ArrayList<Future<Object>>();
// This part of code timeout after 60seconds
responseFutures.add(ask(subActorRef,requestVo, timeout));
}
}
}
SubActor类
public class SubActor extends UntypedActor {
@Resource
@Inject
ServiceAdapter serviceAdapter;
@Override
public void onReceive(Object message) throws Exception {
try{
if (message instanceof BusinessRequestVO) {
BusinessRequestVO requestVo = (BusinessRequestVO)message
// There is no time out here so it waits synchronously
// though Main actor timeouts
ServiceResponse response = serviceAdapter.getWorkOrder(requestVo);
getSender().tell(response, ActorRef.noSender());
} catch (Exception e) {
getSender().tell(new akka.actor.Status.Failure(e), getSelf());
throw e;
}
}
}
}
适配器类
public class ServiceAdapterImpl implements ServiceAdapter{
public ServiceResponse getWorkOrder(BusinessRequestVO request){
// Some code here along with webservice calls
}
}
答案 0 :(得分:0)
你不能像你的孩子一样阻止,因此不能处理任何&#34;停止&#34;父发送给他的消息(演员在读取邮箱中的下一个消息之前一次处理一条消息)。
你最好的选择是包裹&#34;慢&#34;孩子在未来内部执行的一部分,你可以将其传递给父母(详见here)。
通过这种方式,如果您的超时到期,您可以让父母发送自定义&#34;停止计算&#34;消息,并且子actor可以终止未来。请参阅here,了解如何终止未来。
但这可能会引入&#34;脏&#34;根据在执行过程中途终止的特定计算,在应用程序逻辑中声明。
在相关的说明中:为什么要将所有n个请求发送给同一个子actor(你阻止了)?这相当于顺序执行。您应该使子actor非阻塞或(更好)为每个请求创建一个阻塞actor。
编辑:根据OP的要求,添加了片段。它是混合scala和java的伪代码,因为我不是Java语法的超级专家,我主要在Scala中使用它,所以请稍微调整一下:
if (message instanceof BusinessRequestVO) {
new Future (
BusinessRequestVO requestVo = (BusinessRequestVO)message
try {
ServiceResponse response = serviceAdapter.getWorkOrder(requestVo);
getSender().tell(response, ActorRef.noSender());
}
catch (Exception e) {
getSender().tell(new akka.actor.Status.Failure(e), getSelf());
throw e;
}
) pipeTo sender
}
在main中(请参阅here了解java的future.cancel)
if (timeout) future.cancel(true)