Search code examples
akkabroadcast

How to send Akka broadcast message


I'm trying to send a single message to several actors. Investigation led me to the code below, but it doesn't work. The message that's "wrapped" in the Broadcast object disappears, and the plain string ends up in the dead letter box.

Can someone tell me what I'm missing? (Edit: I've added the correction below)

    import akka.actor.{Actor, ActorSystem, Props}
    import akka.routing.{Broadcast, BroadcastRoutingLogic, Router}

    object RouterAndBroadcast {
      class MyRoutee extends Actor {
        override def receive: Receive = {
          case x => println(s"MyRoutee $this got message $x")
        }
      }

      def main(args: Array[String]): Unit = {
        val system = ActorSystem.create("system")
        val mr0 = system.actorOf(Props[MyRoutee])
        val mr1 = system.actorOf(Props[MyRoutee])
        val mr2 = system.actorOf(Props[MyRoutee])
/* This was the error:
        val router = new Router(BroadcastRoutingLogic())
        router.addRoutee(mr1)
        router.addRoutee(mr2) */
// This is the corrected version:
        val router = new Router(BroadcastRoutingLogic())
          .addRoutee(mr1)
          .addRoutee(mr2)

        mr1 ! "Hello number one!"
        mr2 ! "Ahoy two, me old mate!"
        router.route(new Broadcast("Listen up!"), mr0) // vanishes??
        router.route("Listen up!", mr0) // ends up in dead letters
        mr1 ! "Number one, are you still there?"
        mr2 ! "Two, where's the grog?"
        router.route(new Broadcast("Still shouting!"), mr0) // also vanishes

        Thread.sleep(5000)
        system.terminate()
      }
    }

Solution

  • Router.addRoutee returns a copy with the routee added, it doesn't modify ther Router in place, see:

    https://github.com/akka/akka/blob/b94e064a34a7f6a9d1fea55317d5676731ac0778/akka-actor/src/main/scala/akka/routing/Router.scala#L140

      /**
       * Create a new instance with one more routee and the same [[RoutingLogic]].
       */
    def addRoutee(routee: Routee): Router = copy(routees = routees :+ routee)
    

    so instead try

    router = router.addRoutee(mr1).addRoutee(mr2)