I am realy surprised by this case. Have any body any thoughts why this happen?
this works fine each time:
child(name) match {
case Some(ref) => ref ! Ping
case _ =>
val ref = actorOf(PingActor.props, name)
ref ! Ping
}
We are create actor if child is not exist. And then send Ping message.
This sometime hangs up on case of actor already exist:
child(name) getOrElse actorOf(PingActor.props, name) ! GetState
Why?
Short answer
Because of operator precedence your message is sent only when child(name)
returns None
, i.e. getOrElse
is invoked.
Use non-infix method invocation to avoid this:
child(name).getOrElse(actorOf(PingActor.props, name)) ! GetState
Long answer
As per Scala language specification, normally infix operations in Scala are left-associative, and are evaluated from left to right. If that was the case here your code would work fine.
However there are also operator precedence rules which allow usual mathematical and logic operations without parenthesis. According to them, !
operator has higher precedence than getOrElse
and is evaluated prior to it, thus sending message from 'inside'.