在JavaAkka中,在主参与者超时之后,子参与者(工作者)仍然工作

在JavaAkka中,在主参与者超时之后,子参与者(工作者)仍然工作,akka,Akka,我使用Java在Akka框架中实现了一个应用程序。我有一个main-actor,它使用'Ask'方法调用sub-actor,并在60秒后超时,worker在收到main-actor的消息后调用另一个java类方法 现在的问题是,虽然我的主参与者在60秒后超时,但工作人员仍然能够与java类方法对话,而该方法正在执行不需要的操作,因为主参与者无法接收响应,尽管子参与者由于超时而返回响应 如果我的主要参与者超时,我是否可以杀死工人或阻止其进一步处理? 我检查了一些方法,如receivetimeout

我使用Java在Akka框架中实现了一个应用程序。我有一个main-actor,它使用'Ask'方法调用sub-actor,并在60秒后超时,worker在收到main-actor的消息后调用另一个java类方法

现在的问题是,虽然我的主参与者在60秒后超时,但工作人员仍然能够与java类方法对话,而该方法正在执行不需要的操作,因为主参与者无法接收响应,尽管子参与者由于超时而返回响应

如果我的主要参与者超时,我是否可以杀死工人或阻止其进一步处理? 我检查了一些方法,如
receivetimeout()
context.stop()
和毒药丸,但仍然没有用

感谢您的支持

代码如下

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));
        }
    }
}
适配器类

public class ServiceAdapterImpl implements ServiceAdapter{
    public ServiceResponse getWorkOrder(BusinessRequestVO request){
        // Some code here along with webservice calls
    }
}

由于您的子参与者正在阻止,因此无法处理父级向其发送的任何“停止”消息(参与者在读取邮箱中的下一条消息之前,一次处理一条消息)

最好的办法是将孩子执行过程中的“慢”部分包装在一个将来,您可以通过管道将其传递给家长(有关详细信息,请参阅)

通过这种方式,如果超时过期,您可以让父级发送一条自定义的“停止计算”消息,子级参与者可以在将来终止。了解如何终止未来

但这可能会根据在执行中途终止的特定计算在应用程序逻辑中引入“脏”状态

另一个相关的注意事项是:为什么要将所有n个请求发送给同一个子参与者(您进行了阻止)?这相当于顺序执行。您应该使子参与者非阻塞,或者(更好)为每个请求创建一个阻塞参与者

编辑:根据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(参见java的未来。cancel)


“…停止进一步处理…”您的意思是想中断正在进行的调用中的
.getWorkOrder()
?是的,如果父参与者超时等待答复,我想中断.getWorkOrder(),但我已经在使用主参与者中的future,它超时,但是在subactor中,没有办法使subactor超时,因为在subactor中,我调用的是另一个类的普通java函数。1.我可以使用future调用普通java类操作吗,或者这只适用于AKKA参与者/子参与者ask/tell?2.java并发性的未来与AKKA的未来类似吗?请建议我为下面的代码ServiceResponse response=serviceAdapter.getWorkOrder(requestVo)超时的代码片段;未来不是来自Akka,而是Java/scala的东西。你可以在将来包装很多东西,而不仅仅是问。但是通过询问,你可以很容易地将未来传递给发送者。Akka的未来是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
}
if (timeout) future.cancel(true)