3
votes

I have a chain of akka actors like

A --> B --> C

Actor A 'asks' actor B which in turn 'asks' actor C. Actor A needs to wait till actor C has finished processing. B is a thin layer and does nothing more than passing(asking) the message to C and returns a Future back to A. Basically B just do

        { case msgFromA => sender ! C ? msgFromA }

Hence what A is getting is a Future[Any].

The way A is handling the request is using nested maps

actorRefFactory.actorOf(Props[A]) ? msgA map {
        resp =>
          // Type cast Any to Future and use another map to complete processing. 
          resp.asInstanceOf[Future[_]] map {
            case Success =>
              // Complete processing
            case Failure(exc) =>
             // Log error

This works(i.e The final processing happens only when the actor C has finished processing ) but needless to say it looks horrible. I tried using flatmaps but could not make it work. Any ideas to make it look good :) Thanks

1
No. Actor C calls the database and updates the cache. - mohit
Maybe I missed the thumb rule. However this works better than our old implementation using non-actors which was neater. I hate the type cast but I can live with it due to performance benefits that it provides. - mohit

1 Answers

4
votes

A more proper way:

In A:

val f: Future[MyType] = (B ? msg).mapTo[MyType]
f onComplete {
  case Success(res) => // do something
  case Failure(t) => // do something
}

In B, use forward:

{ case msgFromA => C forward msgFromA }

In C:

// call database
// update cache
sender() ! res   // actually sends to A