2014-10-13 3 views
3

У меня есть цепь AKKA актеров, какАкка актеров/Scala - одного OnSuccess для нескольких спрашивает

A --> B --> C 

Актер А «просит» актер B, который в свою очередь «просит» актер С. актеру нужно ждать пока актер C не завершил обработку. B представляет собой тонкий слой, и ничего не делает больше, чем передача (с просьбой) сообщение на C и возвращает будущее обратно к A. В основном B вобще

 { case msgFromA => sender ! C ? msgFromA } 

Поэтому то, что получает это будущее [Любой].

Способ А обработки запроса использует вложенные карты

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 

Это работает (то есть окончательная обработка происходит только тогда, когда актер C закончит обработку), но само собой разумеется, что выглядит ужасно. Я пробовал использовать flatmaps, но не мог заставить его работать. Любые идеи, чтобы сделать его хорошо выглядеть :) Спасибо

+0

Нет. Актер C вызывает базу данных и обновляет кеш. – mohit

+0

Возможно, я пропустил правило большого пальца. Однако это работает лучше, чем наша старая реализация, используя не-актеры, которые были более аккуратны. Я ненавижу тип, но я могу жить с ним из-за преимуществ производительности, которые он предоставляет. – mohit

ответ

4

Более правильный способ:

В A:

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

В B используйте forward:

{ case msgFromA => C forward msgFromA } 

В C:

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

Спасибо. Я проверю его и приму в качестве правильного ответа :) – mohit

+0

Рад, что это помогло :) –

Смежные вопросы