I have been looking into this in more detail and wonder if this could be an 
Akka bug.

The docs say: http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html

Since stopping an actor is asynchronous, you cannot immediately reuse the 
> name of the child you just stopped; this will result in an 
> InvalidActorNameException. Instead, watch the terminating actor and 
> create its replacement in response to the Terminated message which will 
> eventually arrive.
>

I am trying to recreate an actor in response to the Terminated message.  
When I send the Recreate message to the GuardianActor it works most of the 
time but fails nearly one time in 10,000.

class GuardianActor extends Actor {
  val deathReporter = context.actorOf(DeathReportActor.props)
  var fatedOpt: Option[ActorRef] = None
 
  def receive = {
    case Create(value) =>
      fatedOpt = Some(context.actorOf(pheonixProps(value), "someName"))
    case Recreate(value) =>
      fatedOpt foreach { fated =>
        deathReporter ! DeathReportActor.Watch(fated, self, Create(value))
        context.system.stop(fated)
      }
  }
}

 
class DeathReportActor extends Actor {
  import DeathReportActor._
 
  var watches = Map[ActorRef, Watch]()
 
  def receive = {
    case w @ Watch(fated, _, _) =>
      watches += fated -> w
      context.watch(fated)
    case Terminated(fated) =>
      watches.get(fated) foreach {
        case Watch(_, mourner, message) =>
          mourner ! message
      }
  }
}



[INFO] [04/08/2014 16:08:23.670] 
[DeathReportActorTest-akka.actor.default-dispatcher-6] 
[akka://DeathReportActorTest/user/$a/someName] Message 
[akka.dispatch.sysmsg.Suspend] from 
Actor[akka://DeathReportActorTest/user/$a/someName#697148684] to 
Actor[akka://DeathReportActorTest/user/$a/someName#697148684] was not 
delivered. [1] dead letters encountered. This logging can be turned off or 
adjusted with configuration settings 'akka.log-dead-letters' and 
'akka.log-dead-letters-during-shutdown'.
[ERROR] [04/08/2014 16:08:23.671] 
[DeathReportActorTest-akka.actor.default-dispatcher-8] 
[akka://DeathReportActorTest/user/$a] actor name [someName] is not unique!
akka.actor.InvalidActorNameException: actor name [someName] is not unique!
        at 
akka.actor.dungeon.ChildrenContainer$NormalChildrenContainer.reserve(ChildrenContainer.scala:130)
        at akka.actor.dungeon.Children$class.reserveChild(Children.scala:77)
        at akka.actor.ActorCell.reserveChild(ActorCell.scala:369)
        at akka.actor.dungeon.Children$class.makeChild(Children.scala:202)
        at akka.actor.dungeon.Children$class.actorOf(Children.scala:38)
        at akka.actor.ActorCell.actorOf(ActorCell.scala:369)
        at 
DeathReportActorTest$GuardianActor$$anonfun$receive$2.applyOrElse(TestFoo.scala:45)
        at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
        at DeathReportActorTest$GuardianActor.aroundReceive(TestFoo.scala:39)
        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)
        
Could there be a race condition in this code? I found this ticket, but it 
could not be reproduced.
https://www.assembla.com/spaces/akka/tickets/3007-invalidactornameexception-even-after-terminated-received-for-that-nam#/activity/ticket:

Iain.








On Tuesday, 8 April 2014 16:23:01 UTC+1, Iain Hull wrote:
>
> I am using context.watch in a simple DeathReportActor, Clients send the 
> DeathReportActor a Watch message, then when the fated actor dies a 
> specified message is sent to the mourner. I want to use this for restarting 
> actors with different constructor parameters.  However when I test this 
> actor I keep getting intermittent InvalidActorNameExceptions.  
>
> It seems that the actors name is still in use after I receive the 
> Terminated message, so sometimes creating an actor straight away results in 
> an error.  I thought I was guaranteed to be able to recreate the actor upon 
> recipt of the Terminated message, is this correct or do I have bug in my 
> code?
>
> Here is a simple gist that reproduces the error.  I have tested with akka 
> 2.0.5, 2.2.3 and 2.3.1 and get the same results when I retry this operation 
> enough times is a very tight loop.
>
> https://gist.github.com/IainHull/10129911
>
> Thanks,
> Iain.
>
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to