I'm developing an application using Akka, and a thing that kind of bugs me the whole time regards message declaration with the Actor
's. Where should I declare the messages? In the receivers companion object or the senders companion object or on some third place?
Messages should be immutable, since they are shared between different threads. It is a good practice to put an actor's associated messages as static classes in the AbstractBehavior's class. This makes it easier to understand what type of messages the actor expects and handles.
The actor context - the view of the actor cell from the actor. Exposes contextual information for the actor and the current message. There are several possibilities for creating actors (see Props for details on props ): // Java or Scala context. actorOf(props, "name") context.
What is an Actor in Akka? An actor is essentially nothing more than an object that receives messages and takes actions to handle them. It is decoupled from the source of the message and its only responsibility is to properly recognize the type of message it has received and take action accordingly.
In Scala, an actor's behavior is defined by implementing the act method. Logically, an actor is a concurrent process which executes the body of its act method, and then terminates. In Akka, the behavior is defined by using a global message handler which processes the messages in the actor's mailbox one by one.
The Akka team recommends Message should be defined in the same place the props
method should be: in the Receiver's Companion object because the Receiver implements the receive
partial function and needs to know about all the messages it supports. Also, multiple senders can send a set of messages (implemented by the Receiver), so you cannot put it in one single sender.
If the official Typesafe Activator template activator-akka-scala-seed is of any importance regarding Akka's good practices the messages should be part of companion object as shown in the following PingActor
actor (copied directly from the template):
package com.example
import akka.actor.{Actor, ActorLogging, Props}
class PingActor extends Actor with ActorLogging {
import PingActor._
var counter = 0
val pongActor = context.actorOf(PongActor.props, "pongActor")
def receive = {
case Initialize =>
log.info("In PingActor - starting ping-pong")
pongActor ! PingMessage("ping")
case PongActor.PongMessage(text) =>
log.info("In PingActor - received message: {}", text)
counter += 1
if (counter == 3) context.system.shutdown()
else sender() ! PingMessage("ping")
}
}
object PingActor {
val props = Props[PingActor]
case object Initialize
case class PingMessage(text: String)
}
Note PingActor
that holds all the accepted messages by the actor (as you may've noticed it's not followed strictly since PongActor.PongMessage
is also accepted, but not defined in the companion object PingActor
).
From another question How to restrict actor messages to specific types? the Viktor said:
The common practice is to declare what messages an Actor can receive in the companion object of the Actor, which makes it very much easier to know what it can receive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With