Reputation: 61011
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
?
Upvotes: 2
Views: 772
Reputation: 16412
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.
Upvotes: 4