Akka Singleton - do not accept messages

I was stupid - I did not pass on the details of the indexer to the creation of the system. I will leave the answer here if someone takes any benefit *

I create a singleton and send a message like this:

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" 

The numbered line shows non-singlet details that work great

When I run the application, I get the following errors:

 [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 

All other functions stop working, which correlates with the message implying that the actor "coreIndexer" does not receive the message "start_indexing"

More code:

 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 } } } 

Looks like I sent a message to the manager, not a singleton. However, when I send messages to singleton, nothing happens:

 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" } } 
+4
source share
2 answers

The problem you see (I think) is sending a message to the ClusterSingletonManager instead of your actual actor sitting under it. Try to find the actor below if by name ( actorFor ), and it should work.

+2
source

I know this is already allowed, but even with the information presented here, it still took me a while to figure out how to send messages to singleton, and decided that I would leave what I found here.

Two key concepts not well explained by the Cluster Singleton Documentation are as follows:

  • An actor created using ClusterSingletonManager.props is the parent of the actual instance and
  • you should use this actor address only to create ClusterSingletonProxy

Each node in the cluster will create a singleton manager, and the one that finally wins as the oldest is the parent of the singleton you really want to talk to. ClusterSingletonProxy ensures that you are talking to the actual proxy server and that even if a singleton is temporarily unavailable or migrated to another node, you always talk to the corresponding instance.

Given this information, the code should be:

 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" } } 
+2
source

Source: https://habr.com/ru/post/1487453/