Search code examples
scalaakkaactor

Akka Actor Selection


I am maintaining an actor registry as follows:

val system = ActorSystem("MySystem")
val actorRegistry = HashMap[String, ActorRef]()

def process(msg: Message, keys: List[String]): Unit = {
  for (key <- keys) {

    //Lookup the actor or create a new actor and register
    val actor = actorRegistry getOrElseUpdate(key, 
      system actorOf(Props[MyActor], name = key))

    actor ! msg
  }
}

Is this an idiomatic approach, or should I be implementing this with ActorSelection?


Solution

  • You might want to consider using Akka Routing. An example from the doc:

    import akka.routing.ActorRefRoutee
    import akka.routing.Router
    import akka.routing.RoundRobinRoutingLogic
    
    class Master extends Actor {
        var router = {
            val routees = Vector.fill(5) {
                val r = context.actorOf(Props[Worker])
                context watch r
                ActorRefRoutee(r)
            }
            Router(RoundRobinRoutingLogic(), routees)
        }
    
        def receive = {
            case w: Work =>
                router.route(w, sender())
            case Terminated(a) =>
                router = router.removeRoutee(a)
                val r = context.actorOf(Props[Worker])
                context watch r
                router = router.addRoutee(r)
        }
    }
    

    You code looks quite similar to a regular router, i.e. you have a bunch of actors of the same type MyActor processing the same type of messages Message. If you use akka.routing.BroadcastRoutingLogic to send the message to all routees you would achieve something very similar to what you have and you will have all the support of the framework for dealing with failures. The minor difference is that your list of keys might potentially be smaller than actorRegistry but even that could be implemented with custom RoutingLogic if really needed.