2017-02-20 35 views
0

Я реализую актера с несколькими состояниями и используя Stash, чтобы не потерять сообщений. Мои состояния инициализируются (получают что-то из БД), запускают (обрабатывают запросы) и обновляются (обновляя мое состояние). Моя проблема в том, что я теряю сообщения, когда я пытаюсь выполнить unstashAll() в будущем решении.akka unstashAll не работает

def initializing: Receive = { 
case Initialize => 
    log.info("initializing") 
    (for { 
    items1 <- db.getItems("1") 
    items2 <- db.getItems("2") 
    } yield items1 ::: items2) map {items => 
    unstashAll() 
    context.become(running(items)) 
    } 
case r => 
    log.debug(s"actor received message: $r while initializing and stashed it for further processing") 
    stash()} 

я установил ее, изменив свою реализацию этого

def initializing: Receive = { 
case Initialize => 
    log.info("initializing") 
    (for { 
    items1 <- db.getItems("1") 
    items2 <- db.getItems("2") 
    } yield items1 ::: items2) pipeTo self 
    context.become({ 
    case items: List[Item] => 
     unstashAll() 
     context.become(running(items)) 
    case r => 
     log.debug(s"actor received message: $r while initializing and stashed it for further processing") 
     stash() 
    }) 
case r => 
    log.debug(s"actor received message: $r while initializing and stashed it for further processing") 
    stash()} 

может кто-нибудь объяснить, почему первый не работает?

ответ

1

Я думаю, что unstashAll часть работает нормально. Проблема в том, что вы ее запускали - вместе с вашим context.become - как часть будущего обратного вызова.

Это означает, что код внутри вашего блока map избегает предсказуемости последовательной обработки вашего актера. Другими словами, это могло произойти:

  1. вы звоните unstashAll
  2. ваши сообщения помещаются обратно в почтовый ящик актера
  3. актер поднимает свои сообщения один за другим. Контекст до сих пор не изменилось, так что они спрятали снова
  4. ваш контекст, наконец, становится running (но это слишком поздно)

решение - как вы выяснили - в pipeTo узор, который по существу Посылает Future s результат для актера как сообщения. Это делает его последовательным и предсказуемым.