2013-06-21 2 views
4

Это был я, будучи глупым - я не передавал реквизиты индексатора в создание системы. Я оставлю ответ здесь, в случае, если кто принимает какую-то пользу *Akka Singleton - непринятие сообщений

Я создаю одноплодный и отправляю сообщение, как это:

val indexerProps = ClusterSingletonManager.props(had => Props(
      classOf[SingleCoreIndexer], dataProvider, publisher, name), name, End, None) 

     val coreIndexer = system.actorOf(indexerProps, name) 
     //val coreIndexer = system.actorOf(Props(classOf[SingleCoreIndexer], dataProvider, publisher, name)) 

     coreIndexer ! "start_indexing" 

Закомментированных вне линии показывает не-одноэлементный реквизит, что работать нормально

Когда я запустить приложение я получаю следующие ошибки:

[WARN] [06/21/2013 11:55:32.443] [deadcoreindexerstest-akka.actor.default-dispatcher-5] [akka://deadcoreindexerstest/user/node1] unhandled event start_indexing in state Start 

Все другой функциональности перестает работать, какой correla тес с сообщением подразумевающего «coreIndexer» актер не получает сообщение «start_indexing»

Подробнее кода:

class Indexer(systemCreator: SystemCreator, publisherProps: Props, dataProviderProps: Props, name: String) { 

    def start { 
     val system = systemCreator.create 
     val dataProvider = system.actorOf(dataProviderProps) 
     val publisher = system.actorOf(publisherProps) 

     val indexerProps = ClusterSingletonManager.props(
      singletonProps = had => Props(classOf[SingleCoreIndexer], dataProvider, publisher, name), 
      singletonName = "aaa", 
      terminationMessage = End, 
      role = None 
      ) 

     val coreIndexer = system.actorOf(Props(classOf[SingleCoreIndexer], dataProvider, publisher, name)) 
     coreIndexer ! "start_indexing" 
    } 
} 



class SingleCoreIndexer(dataProvider: ActorRef, publisher: ActorRef, name: String) extends Actor { 

    def receive = { 

     case "start_indexing" => { 
      println("Single core indexer starting indexing") 
      dataProvider ! new NextBatchOfDataPlease 
     } 

     case BatchOfData(data) => { 
      publisher ! (name, data) 
      self ! "next_batch" 
     } 

     case "next_batch" => { 
      dataProvider ! new NextBatchOfDataPlease 
     } 
    } 
} 

Похоже, я отправлял сообщение менеджера, а не одиночки. Тем не менее, когда я отправлять сообщения синглтона, ничего не происходит:

class Indexer(systemCreator: SystemCreator, publisherProps: Props, dataProviderProps: Props, name: String) { 

    def start { 
     val system = systemCreator.create 
     val dataProvider = system.actorOf(dataProviderProps) 
     val publisher = system.actorOf(publisherProps) 

     val indexerProps = ClusterSingletonManager.props(
      singletonProps = had => Props(classOf[SingleCoreIndexer], dataProvider, publisher, name), 
      singletonName = "singlecoreindexer", 
      terminationMessage = End, 
      role = None 
      ) 

     system.actorOf(Props(classOf[SingleCoreIndexer], dataProvider, publisher, name)) 
     val coreIndexer = system.actorSelection(s"/user/$name/singlecoreindexer") 
     coreIndexer ! "start_indexing" 
    } 
} 
+0

Вы можете поделиться код для 'SingleCoreIndexer'? Похоже, что это какая-то проблема, связанная с FSM. – cmbaxter

+0

Забавно, вы пришли на свой ответ, пока я отправлял мой, что было тем же самым. – cmbaxter

+2

Используйте 'ClusterSingletonProxy' для доступа к игроку за менеджером singleton. –

ответ

2

Проблема вы видите (я думаю) происходит от вас отправки сообщения на ClusterSingletonManager вместо вашему действительному актера, который сидит под ним. Попробуйте найти актера внизу, если по имени (actorFor) и он должен работать.

2

Я знаю, что это уже решен, но даже с информацией, представленной здесь, это еще мне потребовалось некоторое время больше времени, чтобы выяснить, как отправлять сообщения одноточечного и полагал, что я оставил бы то, что я нашел здесь

два ключевых понятия не хорошо объяснимые Cluster Singleton документации таковы:

  1. актер создал с ClusterSingletonManager.props является родителем фактического экземпляра и
  2. вы должны использовать адрес этого актера только создать ClusterSingletonProxy

Каждый узел кластера создаст диспетчер singleton, а тот, который, наконец, станет победителем, станет самым старым родителем одного синглтона, с которым вы действительно хотите поговорить. ClusterSingletonProxy гарантирует, что вы говорите с фактическим прокси-сервером, и даже если одноэлемент временно недоступен или переносится на другой узел, вы всегда разговариваете с соответствующим экземпляром.

Учитывая, что информация, код должен быть:

class Indexer(systemCreator: SystemCreator, publisherProps: Props, dataProviderProps: Props, name: String) { 

    def start { 
    val system = systemCreator.create 
    val dataProvider = system.actorOf(dataProviderProps) 
    val publisher = system.actorOf(publisherProps) 

    val indexerProps = ClusterSingletonManager.props(
     singletonProps = had => Props(classOf[SingleCoreIndexer], dataProvider, publisher, name), 
     singletonName = "singlecoreindexer", 
     terminationMessage = End, 
     role = None 
    ) 

    val singletonManager = system.actorOf(
     Props(classOf[SingleCoreIndexer],dataProvider, publisher, name) 
    ) 

    val indexerPath = (singletonManager.path/name) 
    val coreIndexer = system.actorOf(
     ClusterSingletonProxy.props(indexerPath, None), 
     s"$name-proxy" 
    ) 

    coreIndexer ! "start_indexing" 
    } 
}