Akka终止未发送或路由到其他地方的消息

Akka终止未发送或路由到其他地方的消息,akka,router,actor,terminate,Akka,Router,Actor,Terminate,我有几个演员,每个演员都有多个路由器,用于特定类型的演员。我创建了一个类RouteeTracker(你猜对了)来跟踪每种类型的路由器所属的角色。这是为了正确处理来自每种类型的参与者的终止消息 public class RouteeTracker { private static final Logger logger = LoggerFactory.getLogger(RouteeTracker.class); private Map<ActorRef, Router&g

我有几个演员,每个演员都有多个路由器,用于特定类型的演员。我创建了一个类RouteeTracker(你猜对了)来跟踪每种类型的路由器所属的角色。这是为了正确处理来自每种类型的参与者的终止消息

public class RouteeTracker
{
    private static final Logger logger = LoggerFactory.getLogger(RouteeTracker.class);

    private Map<ActorRef, Router> routeeRouterMap = new HashMap<ActorRef, Router>();
    private Map<ActorRef, Class> routeeClassMap = new HashMap<ActorRef, Class>();
    private Map<Class, String> routeeDispatcherMap = new HashMap<Class, String>();

    Router register(Class actorClass, int actorPoolCount, UntypedActorContext untypedActorContext, RoutingLogic routingLogic, ApplicationContext applicationContext, String dispatcher)
    {
        List<Routee> routees;
        List<ActorRef> actors;

        routees = new ArrayList<>();
        actors = new ArrayList<>();

        for (int i = 0; i < actorPoolCount; i++) {
            ActorRef r = untypedActorContext.actorOf(Props.create(actorClass, applicationContext).withDispatcher(dispatcher));
            logger.info("r={}",r.toString());
            actors.add(r);
            **untypedActorContext.watch(r);**
            routees.add(new ActorRefRoutee(r));
        }

        **Router router = new Router(routingLogic, routees);**
        routeeDispatcherMap.put(actorClass, dispatcher);

        for(ActorRef actor:actors)
        {
            routeeRouterMap.put(actor, router);
            routeeClassMap.put(actor, actorClass);
        }

        return router;
    }

    ActorRef handleTerminate(ActorRef actorRef, UntypedActorContext untypedActorContext)
    {
        logger.info("Entering RouteeTracker.handleTerminate({,{})",actorRef.toString(), untypedActorContext.toString());
        Router router = routeeRouterMap.get(actorRef);
        if(router == null)
            throw new RuntimeException("No router found for actorRef");

        Class actorClass = routeeClassMap.get(actorRef);
        String dispatcher = routeeDispatcherMap.get(actorClass);
        if(actorClass == null)
            throw new RuntimeException("No actorClass found for actorRef");

        **strong text**router.removeRoutee(actorRef);
        logger.info("####class:dispatcher {}:{}",actorClass.toString(),dispatcher);

        ActorRef r = untypedActorContext.actorOf(Props.create(actorClass).withDispatcher(dispatcher));
        untypedActorContext.watch(r);
        router.addRoutee(new ActorRefRoutee(r));

        //Cleanup
        routeeRouterMap.remove(actorRef);
        routeeClassMap.remove(actorRef);

        logger.info("Exiting RouteeTracker.handleTerminate({,{})",actorRef.toString(), untypedActorContext.toString());
        return r;
    }
}
公共类路由跟踪器
{
私有静态最终记录器Logger=LoggerFactory.getLogger(RouteeTracker.class);
私有映射routeeRouterMap=newHashMap();
私有映射routeeClassMap=newHashMap();
私有映射RouteDispatcherMap=newHashMap();
路由器寄存器(类actorClass、int actorPoolCount、UntypedActorContext UntypedActorContext、路由逻辑路由逻辑、应用上下文应用上下文、字符串分派器)
{
列出路线;
列出行动者名单;
routees=新的ArrayList();
actors=newarraylist();
for(int i=0;i
我在这样一个演员身上使用这个路由器:

public class Supervisor extends UntypedActor {
    private static final Logger logger = LoggerFactory.getLogger(Supervisor.class);

    public static Props props(final ApplicationContext applicationContext) {
        return Props.create(new Creator<Supervisor>() {
            private static final long serialVersionUID = 1L;
            @Override
            public Supervisor create() throws Exception {
                return new Supervisor(applicationContext);
            }
        });
    }

    private ApplicationContext applicationContext;
    public ApplicationContext getApplicationContext() { return applicationContext; }
    public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; }


    private Router SIPRRouter;
    private Router SICRouter;
    private Router VFERouter;
    private RouteeTracker routeeTracker = new RouteeTracker();

    public Supervisor(ApplicationContext applicationContext)
    {
        this.applicationContext = applicationContext;
        sessionIdentifierGenerator = (SessionIdentifierGeneratorService) this.applicationContext.getBean("sessionIdentifierGeneratorServiceImpl");
     }

    @Override
    public void preStart() throws Exception {
        SIPRouter = routeeTracker.register(SIEProducer.class, 5, **getContext()**, new RoundRobinRoutingLogic(), applicationContext, "si-bio-d");
        SICRouter = routeeTracker.register(SIEConsumer.class, 5, **getContext()**, new RoundRobinRoutingLogic(), applicationContext, "si-bio-d");
        vfeRouter = routeeTracker.register(VFE.class, 10, **getContext()**, new RoundRobinRoutingLogic(), applicationContext, "fe-bio-d");
    }

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof String) {

            String msg = (String) message;
            logger.debug("Supervisor::Received String message: {}", msg);

        } else if(message instanceof Terminated) {
            logger.info("handle terminated");
            routeeTracker.handleTerminate(((Terminated) message).actor(),getContext());
        } else {
            unhandled(message);
        }
        message = null;
    }

}
公共类主管扩展了UntypedActor{
专用静态最终记录器记录器=LoggerFactory.getLogger(Supervisor.class);
公共静态道具道具(最终应用程序上下文应用程序上下文){
返回道具。创建(新创建者(){
私有静态最终长serialVersionUID=1L;
@凌驾
公共主管create()引发异常{
返回新主管(applicationContext);
}
});
}
私有应用程序上下文应用程序上下文;
公共应用程序上下文getApplicationContext(){return ApplicationContext;}
public void setApplicationContext(ApplicationContext ApplicationContext){this.ApplicationContext=ApplicationContext;}
专用路由器;
专用路由器;
专用路由器VFERouter;
专用RouteeTracker RouteeTracker=新RouteeTracker();
公共主管(应用上下文应用上下文)
{
this.applicationContext=applicationContext;
sessionIdentifierGenerator=(SessionIdentifierGeneratorService)this.applicationContext.getBean(“sessionIdentifierGeneratorServiceImpl”);
}
@凌驾
public void preStart()引发异常{
SIPRouter=routeeTracker.register(SIEProducer.class,5,**getContext()**,新RoundRobinRoutingLogic(),applicationContext,“si-bio-d”);
SICRouter=routeeTracker.register(SIEConsumer.class,5,**getContext()**,新RoundRobinRoutingLogic(),applicationContext,“si-bio-d”);
vfeRouter=routeeTracker.register(VFE.class,10,**getContext()**,新RoundRobinRoutingLogic(),applicationContext,“fe-bio-d”);
}
@凌驾
public void onReceive(对象消息)引发异常{
if(字符串的消息实例){
字符串消息=(字符串)消息;
debug(“Supervisor::Received String message:{}”,msg);
}else if(消息instanceof Terminated){
logger.info(“句柄终止”);
routeeTracker.handleTerminate(((终止)message.actor(),getContext());
}否则{
未处理(消息);
}
消息=null;
}
}
为了清晰起见,我删除了许多与处理终止消息无关的消息。问题是参与者从未收到终止消息。因此,我的RouteeTracker.HandleteTerminated()方法从未被调用。我只能假设消息从未被发送,可能是因为这些子参与者没有终止,或者终止消息没有被发送

我的路由器使用基于Typesafe官方Akka Java文档

我调用untypedActor.watch(…),并在routeeTracker的register方法中添加新创建的actor

我在routeeTracker的terminate方法中将actor从路由器(和其他数据结构)中移除

儿童演员似乎没有被监视


有人想吗?

答案是42。答案是42。