我该如何将一个阿卡演员的永恒信息暴露给非演员的世界



我正在努力处理actor系统和非actor代码的交互。AkkaJava文档的第3.2.1节描述了使用TypedActors在Actor系统和外部非Actor世界之间执行桥接。

类型化的actor非常适合在actor系统("内部")和非actor代码("外部")之间进行桥接,因为它们允许您在外部编写看起来像OO的普通代码。

然后描述了三种不同的场景:

  • 单向消息发送
  • 请求回复消息发送
  • 请求回复并在将来发送消息

但所有这些场景都是从非行动者的世界开始的。actor系统调用非actor代码的正确方式是什么?

我试图做的是将actor消息的不可变有效负载直接暴露给非actor世界。例如,参与者A将其从参与者B接收的消息的不可变有效载荷(比如映射)保留为易失性实例变量,然后出于性能原因(通过普通getter或facade)将该变量暴露给非参与者世界。该映射是不可变的,因此它本质上是线程安全的,因此不需要路由消息等开销。Actor A被许多非Actor线程访问,每隔一段时间,它就会从Actor B接收更新的映射。

public class ActorAFacade extends UntypedActor implements Map<String, String> {
    private volatile Map<String, String> immutableMap = Collections.emptyMap();
    @Override
    public String get(Object key) {
       return immutableMap.get(key);
    }
    @Override
    public String put(String key, String value) {
        throw new UnsupportedOperationException("Read Only!");
    }
    ... 
    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof Map) {            
            immutableMap = (Map<String, String>) message;
        } else {
            unhandled(message);
        }
    }
}

我希望避免为每个映射方法创建和路由消息的开销(无论是由非类型化的参与者手动完成还是由类型化的行动者自动完成)。

这种混合方法是可行的解决方案吗(它是否违反了行动者系统的精神)?Akka是否提供了更好的方法(即事件总线、回叫等)?

您可能需要查看"代理"或"期货和代理"一章。

我不确定非演员世界到底在问什么,你的意思是问吗?

ActorSystem system = ActorSystem.create("system");
ActorRef actor = system.actorOf(Props.create(SomeActor.class), "someActor");
Timeout t = new Timeout(5, TimeUnit.SECONDS);
Future<Object> future = Patterns.ask(actor, "some message", 1000);
try {String response = (String) Await.result(future, t.duration());} catch(Exception e){}

所以基本上,您将消息作为"某种消息"发送给SomeActor参与者,然后在它的onReceive方法中,您需要有

    public void onReceive(Object msg) throws Exception
    {
            if (msg instancof String)
            {
                getSender().tell("here is the response");
            }
    }

所以如果你做一个System.out.println(response),它会打印"这是响应"但是,是的,可以使用评论中显示的代理,但它们让我抓狂(;

最新更新