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