Routers
Creating multiple instances of an actor
In the last two posts we’ve looked at dispatchers, how they work, and how we can implement bulkheads with dispatchers to ensure that damage from one part of the app doesn’t adversely affect the other. In this post we’ll begin talking about routers.
previous post:
Routers
A router is responsible for routing messages between multiple actors. You can create a router yourself or use one that ships with Akka. Routers are used in conjunction with dispatchers to get the maximum performance out of the application.
A router may be created manually, where you specify the routing logic and the child actors who will receive the messages or you may create a self-contained router which is responsible for routing as well as creating the child actors.
The child actors who will receive the messages are called as “routees”.
Types of routers
In most cases, you’ll use one of the routers that comes with Akka. In this section we’ll look at the routers that come with Akka.
Round-robin router
A round-robin router sends messages to the routees in a round-robin fashion.
Random router
Routes the message to one of the routees at random.
Balancing pool router
In a balancing pool router, all routees share the same mailbox. The router tries to distribute the messages between busy and idle routees. This router automatically used the balancing dispatcher and will ignore any other dispatcher.
Smallest mailbox router
Routes the message to the actor with the smallest mailbox.
Broadcast router
A broadcast router will broadcast the same message to all the routees.
Scatter-gather first completed router
This router sends the message to all the routees and waits for the first response within a specified period of time.
Tail chopping router
Tail chopping router sends the message first to a randomly picked routee and then to another one, after a delay, and so on. It then waits for the reply. It keeps the first one and discards the rest.
Consistent hashing router
This router uses consistent hashing to decide which routee will receive the message.
Adding a router
A router may be added from the configuration file or from code. We’ll add routers from code. Go ahead and update the GreetingsActor’s companion object to the following:
We’ve added a few helper methods to easily use routers. Next, we’ll update the SupervisorActor to make use of these routers.
Notice that we’re creating 3 instances of the GreetingsActor and using a random router to route the messages (line 11).
and finally, update the main app
When you run the app, you may get a zero count response. This is because the hello message may be delivered to one router and the count message to another. That’s it. We’ve added a router to our application. Feel free to play around with the routers and see what difference they make in the output.
What we’ve created here is a self-contained router. This router is responsible for creating the child instances and also supervising them. We haven’t added any supervision yet but we will, soon.
Contrast what we’ve done with the example below (taken from the docs):
Here we’d have to create the routees, specify the routing logic, and also monitor the lifecycle. However, all this is handled in a self-contained router. The only additional thing we’d have to specify is the routing logic.
Router group vs router pool
We’ve used router pools in our example. Router pools are responsible for creating their routees and managing them. Sometimes, we may wish to create routees separately and route messages to them. In such cases, we use a router group. A router group manages routees in a different actor system.
That’s it for this post on routers.