我正在努力处理参与者系统和非参与者代码的交互。Akka Java 文档的第 3.2.1 节描述了使用 TypedActors 在 Actor 系统和外部非 Actor 世界之间进行桥接。
类型化的 Actor 非常适合在 Actor 系统(“内部”)和非 Actor 代码(“外部”)之间架起桥梁,因为它们允许您在外部编写正常的 OO 外观代码。
然后继续描述三种不同的场景:
- 单向消息发送
- 请求-回复消息发送
- Request-reply-with-future 消息发送
但所有这些场景都是从非演员世界开始的。演员系统调用非演员代码的正确方法是什么?
我想要做的是将参与者消息的不可变负载直接暴露给非参与者世界。例如,actor A 保留它从actor B 接收到的消息的不可变负载(例如映射)作为 volatile 实例变量,然后出于性能原因(通过普通 getter 或正面)。该映射是不可变的,因此它本质上是线程安全的,因此不需要路由消息等开销。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 是否提供了更好的方法(即事件总线、回调等)?