Remember that you have an asynchronous system here. The reason you are not seeing the correct count in your assertion is that the count is being checked before the entire tree of actors has been created. You can verify this by putting a sleep for a couple of seconds before the call to p.send
. This is also probably the reason you are getting deadletters as you are shutting the system down before it's had time to set itself up. The apex
actor is probably terminated but still receiving AddChild
messages from the subordinates that are trying to be created while things are shutting down.
scala akka: random deadLetters while no actor is asked to stop
-
24-09-2022 - |
Question
I am chaining actors in akka-scala and at each step, the newly created actor will send a message to the supervisor actor. In response, the supervisor will increment a counter.
I don't understand why during this operations deadLetters
are produced at random, sometimes no deadLetters
, sometimes I get a few.
Moreover it appears that the supervisor does not increment the counter. Here's my code
import akka.actor._
object ScopeMessages{
case object AddChild
case object Counter
}
class ScopeSet(n: Int) extends Actor{
import ScopeMessages._
var root:ActorRef = context.actorOf(Props(classOf[ScopeActor],n, self))
var counter = 0
def receive:Receive = {
case AddChild => counter += 1
case Counter => sender ! counter
case _ => ()
}
}
class ScopeActor(id: Int, apex:ActorRef) extends Actor{
import ScopeMessages._
var sub:List[ActorRef] = Nil
if (id > 0){
sub = context.actorOf(Props(classOf[ScopeActor], id-1, apex))::Nil
apex ! AddChild
}
def receive:Receive = {case _ => ()}
}
object ScopeTest extends App {
import akka.testkit.TestProbe
import ScopeMessages._
implicit val system = ActorSystem("TestSys")
val p = TestProbe()
val n:Int = 10
val base_actor = system.actorOf(Props(classOf[ScopeSet], n))
p.send(base_actor, Counter)
p.expectMsg(n)
system.shutdown()
}
Thanks for help.
Solution
OTHER TIPS
Everything cmbaxter said is true. Here's some hints on a way to fix it. Try constructing ScopeSet with the ActorRef of your TestProbe and adding a condition to you receive of AddChild. Also don't shut the actor system until the testProb has received the counter.
class ScopeSet(n: Int, testProb: ActorRef) extends Actor{
import ScopeMessages._
var root:ActorRef = context.actorOf(Props(classOf[ScopeActor],n, self))
var counter = 0
def receive:Receive = {
case AddChild => {
counter += 1
if (counter == n) { testProb ! counter }
}
case _ => ()
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow