Akka和双向演员对话

时间:2015-06-19 02:47:54

标签: synchronization akka messaging actor

基于Akka的演员消息感觉就像是从一些“上游”演员到一个或多个“下游”演员的单向流/消息流。

但是,对于两个actor之间的某种双向(请求/响应)同步消息传递,可能存在合法的用例。例如,我可能有CacheActor来管理一些缓存。其他参与者可能希望putget缓存此缓存的条目,他们需要通过CacheActor执行此操作:

// Groovy pseudo-code
class CacheActor extends UntypedActor {
    Map<String,Object> cache

    // ...

    @Override
    void onReceive(Object message) {
        if(message instanceof GetCacheEntry) {
            GetCacheEntry getCacheEntry = message as GetCacheEntry
            String entry = cache.get(getCacheEntry.key)

            // Now what? How to send back to the actor that called this?!?
            getCacheEntry.sender.tell(new GetCacheEntryResult(getCacheEntry.buzz, entry))   // <-- 2. return to sender (again with 'buzz' as sidecar)
        }
    }
}

class FizzActor extends UntypedActor {
    ActorRef cacheActor

    @Override
    void onReceive(Object message) {
        if(message instanceof Buzz) {
            Buzz buzz = message as Buzz
            cacheActor.tell(new GetCacheEntry(buzz, this))  // <-- 1. identify 'this' as the sender and pass 'buzz' in as sidecar
        } else if(message instanceof GetCacheEntryResult) { // <-- 3. recognize that we are processing the result from #1 above
            GetCacheEntryResult result = message as GetCacheEntryResult
            Buzz originalBuzz = result.buzz
            String resultantEntry = result.entry

            // 4. Now keep processing...
        }
    }
}

这是我能够设想以“会话式”请求 - 响应方式在两个演员之间来回传递消息的唯一方法。问题在于它有点讨厌:

  • 我必须为发送回请求者的每个响应创建新的消息类型(例如GetCacheEntryResult),这将快速膨胀代码;和
  • 每当一个演员回应另一个演员时,“范围内”的所有“上下文变量”可能需要捆绑起来并作为sidecars发送回请求演员,以便他们请求者在收到答案并需要继续处理时可以使用(请参阅下面的buzz)。在几个演员之间的一个更复杂的编排中,这个“上下文映射”会变得相当大;和
  • 在一天结束时,这个解决方案只是感觉就像代码味道一样......

所以我问:在Akka有更好的方法吗?也许使用Futuresask(...)方法?

0 个答案:

没有答案