activator-akka-cluster-sharding-scala InvalidActorNameException
[Tested with Akka 2.3.0, akka-persistence-mongo-casbah 0.0.8 (https://github.com/scullxbones/akka-persistence-mongo/), see here for the branch with this configuration: https://github.com/rocketraman/activator-akka-cluster-sharding-scala/tree/mongodb-journal]
This is based on the discussion @ this thread.
To reproduce, run the activator akka-cluster-sharding example like
1. sbt "run-main sample.blog.BlogApp 2551"
2. sbt "run-main sample.blog.BlogApp 2552"
3. sbt "run-main sample.blog.BlogApp 0"
To reproduce, stop the second node (2552) immediately after seeing a log message starting with "New post saved:". A few seconds later, in the bot node, you may see the Exception:
It seems to be a timing issue as sometimes you have to try to stop the 2552 node multiple times before the error condition occurs. If it does not occur, simply restart the 2552 node and try again. I can usually make it happen within a couple of tries.
This is based on the discussion @ this thread.
To reproduce, run the activator akka-cluster-sharding example like
1. sbt "run-main sample.blog.BlogApp 2551"
2. sbt "run-main sample.blog.BlogApp 2552"
3. sbt "run-main sample.blog.BlogApp 0"
To reproduce, stop the second node (2552) immediately after seeing a log message starting with "New post saved:". A few seconds later, in the bot node, you may see the Exception:
[ERROR] [04/02/2014 13:06:54.120] [ClusterSystem-akka.actor.default-dispatcher-40] [akka://ClusterSystem/user/sharding/AuthorListing] actor name must not be empty
akka.actor.InvalidActorNameException: actor name must not be empty
at akka.actor.dungeon.Children$class.checkName(Children.scala:180)
at akka.actor.dungeon.Children$class.actorOf(Children.scala:38)
at akka.actor.ActorCell.actorOf(ActorCell.scala:369)
at akka.contrib.pattern.ShardRegion$$anonfun$6.apply(ClusterSharding.scala:802)
at akka.contrib.pattern.ShardRegion$$anonfun$6.apply(ClusterSharding.scala:798)
at scala.Option.getOrElse(Option.scala:120)
at akka.contrib.pattern.ShardRegion.deliverMessage(ClusterSharding.scala:798)
at akka.contrib.pattern.ShardRegion$$anonfun$receiveCoordinatorMessage$2.apply(ClusterSharding.scala:694)
at akka.contrib.pattern.ShardRegion$$anonfun$receiveCoordinatorMessage$2.apply(ClusterSharding.scala:693)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at akka.contrib.pattern.ShardRegion.receiveCoordinatorMessage(ClusterSharding.scala:693)
at akka.contrib.pattern.ShardRegion$$anonfun$receive$3.applyOrElse(ClusterSharding.scala:656)
at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
at akka.contrib.pattern.ShardRegion.aroundReceive(ClusterSharding.scala:586)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
at akka.dispatch.Mailbox.run(Mailbox.scala:220)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
It seems to be a timing issue as sometimes you have to try to stop the 2552 node multiple times before the error condition occurs. If it does not occur, simply restart the 2552 node and try again. I can usually make it happen within a couple of tries.
Leave a comment
on 2014-04-02 17:22 *
By rocketraman
Description changed from [Tested with Akka 2.3.0, ak... to [Tested with Akka 2.3.0, ak...
on 2014-04-02 17:22 *
By rocketraman
Description changed from [Tested with Akka 2.3.0, ak... to [Tested with Akka 2.3.0, ak...
on 2014-04-03 06:41 *
By Patrik Nordwall
This is a bug in the sample code. I can see how this can happen.
The Bot is sending the sequence AddPost, ChangeBody, Publish.
The AddPost message is lost. The Bot later sends Publish and the Post will construct PostSummary message with author == "" and send to AuthorListing.
Someone suggested that the Post should use become instead of starting with this PostContent.empty state. That is probably a very good idea. become is not really working for EventsourcedProcessor in 2.3.0, and 2.3.1 has other problems. I will fix the sample as soon as 2.3.2 is out.
I will also add checks and better error message for id == "".
The Bot is sending the sequence AddPost, ChangeBody, Publish.
The AddPost message is lost. The Bot later sends Publish and the Post will construct PostSummary message with author == "" and send to AuthorListing.
Someone suggested that the Post should use become instead of starting with this PostContent.empty state. That is probably a very good idea. become is not really working for EventsourcedProcessor in 2.3.0, and 2.3.1 has other problems. I will fix the sample as soon as 2.3.2 is out.
I will also add checks and better error message for id == "".
on 2014-04-03 07:23 *
By Patrik Nordwall
Assigned to set to Patrik Nordwall
Status changed from New to Accepted
on 2014-04-03 15:53 *
By rocketraman
The AddPost message is "lost"?
Shouldn't the activator be showing how to avoid that "lost" message? I think that would be to have the Bot receive an acknowledgement from Post that the persist was successful, and if it receives an acknowledgement, it would continue to ChangeBody, etc. If it does not receive the ack, it would retry the Post. Or perhaps the Bot should use a reliable channel to send to Post? Or at least, the activator tutorial should discuss this possibility and explain the options to deal with it.
Lastly, if 'log.info("New post saved: {}", state.content.title)' was moved outside the persist block, would it more accurately reflect when the post had actually been persisted? Or is that not a guarantee since the persistence could be asynchronous?
(Thanks Roland)
Shouldn't the activator be showing how to avoid that "lost" message? I think that would be to have the Bot receive an acknowledgement from Post that the persist was successful, and if it receives an acknowledgement, it would continue to ChangeBody, etc. If it does not receive the ack, it would retry the Post. Or perhaps the Bot should use a reliable channel to send to Post? Or at least, the activator tutorial should discuss this possibility and explain the options to deal with it.
Lastly, if 'log.info("New post saved: {}", state.content.title)' was moved outside the persist block, would it more accurately reflect when the post had actually been persisted? Or is that not a guarantee since the persistence could be asynchronous?
(Thanks Roland)
on 2014-04-11 11:20 *
By Patrik Nordwall
@rocketraman I have changed the activator template to use become, and added the "lost" message as an exercise. See https://github.com/typesafehub/activator-akka-cluster-sharding-scala/pull/6
Regarding "New post saved: {}" I think you misunderstand something. The persist block is called when the post was successfully stored.
Regarding "New post saved: {}" I think you misunderstand something. The persist block is called when the post was successfully stored.
on 2014-04-12 21:09 *
By rocketraman
Thanks for the fixes / update of the tutorial and for the clarification on the persist block.