Communication Patterns
Different ways to pass messages
In the previous post we created a SupervisorActor which supervises our GreetingsActor. The SupervisorActor did two things — send Hello message over to GreetingsActor, and ask it the count of the messages it has received so far.
previous post:
That is, we’ve seen two communication patterns — tell (!) and ask (?). In this post we’ll talk about communication patterns among actors.
Tell
In the SupervisorActor, whenever we received a Hello message, we just sent it over to the GreetingsActor. What we did was “tell”. The SupervisorActor told the GreetingsActor about a new message.
A “tell” operation is fire-and-forget — you send the message asynchronously and move on. The effect of “tell” is that for GreetingsActor, the sender reference will refer to the SupervisorActor.
Ask
Another thing that we did in SupervisorActor was asking the GreetingsActor about the count of messages it had received. What we did was “ask”. Whenever we “ask” another actor for some information, we get back a Future which may eventually be completed. This future is completed when the receiving actor sends a message back to the sender.
Behind the scenes, Akka creates an actor for its internal use which receives the completed value of the future. We’re required to provide a timeout value because that decides how long this internal actor will exist before being destroyed to prevent memory leaks.
What we did in our code next was to synchronously wait for the Future to resolve as shown below
If the future doesn’t resolve within the specified time, we’d get an exception.
Another thing we could do with this future is piping. Piping allows us to feed the value of the Future to another actor as a message. This is much better than synchronously waiting for a response.
Here’s how you’d modify the SupervisorActor to receive the completed value of the Future
Once the Future completes, we want its value to be sent back to the SupervisorActor which is referenced by “self”. We need to add another case in our partial function to handle the value of this future.
Forward
One thing we did not look at is forwarding messages. Forwarding messages is similar to “tell”-ing messages with a subtle difference — a “forward” does not modify the sender of the messages.
Presently, the GreetingsActor is responsible for keeping the count of the number of messages it has received. What if instead we wanted to have a separate actor whose only job is to keep track of the counts of the messages received and forward them to appropriate actors? Something like this:
SupervisorActor → CountActor → GreetingsActor
Now what the CountActor would do is increment the count and “forward” the message to the GreetingsActor and because it is a “forward”, the “sender” still refers to SupervisorActor. When the GreetingsActor responds to the message, it goes straight to the SupervisorActor like so:
SupervisorActor ← GreetingsActor
You can read more about message forwarding in the docs: http://doc.akka.io/docs/akka/current/scala/actors.html#Forward_message
That’s it for this post.