Reputation: 40461
In most examples of proper usage of the scala (and akka) actor frameworks, people tend to derive every message from a single trait. For example:
trait Message
object Ping extends Message
object Pong extends Message
However, in both Scala and Akka, message reception is not typed at all. Is there any reason to implement a common trait ?
Upvotes: 11
Views: 1069
Reputation: 20619
Both with scala.actors
(via InputChannel[T]
or Reactor[T]
) and Akka (TypedActor
) you can set type bounds for the incoming messages;
In the most examples, messages extend a sealed trait
. That's done for 2 reasons:
if the message handler (partial function) of your actor doesn't cover all the messages that extend the trait, compiler generates a warning;
sealed trait
can be extended only in the source file, where the trait is defined, and, thus, client cannot define it's own messages that extend the trait;
Upvotes: 5
Reputation: 25781
This really depends on what you are trying to achieve. For example, I recently built a small application using actors which had several types of actors, and a managing actor which acted more or less like a router. Now, the working actors could receive lots of different messages, for example Foo
, Bar
and Baz
. Without a Supertype, in the managing actor I'd have to write something like this:
react {
case x:Foo | x:Bar | x:Baz => worker ! x
}
Which is obviously unnecessarily verbose. So in this case, a supertype WorkerMessage
would make a lot of sense, because it simplifies your code:
react {
case x:WorkerMessage => worker ! x
}
On the other hand, this makes the messages Foo
, Bar
and Baz
pretty much unusable for any other purpose than being used by your WorkerActors. If you had a message Stop
or Init
for example, this would probably be bad because you'd need to redefine it all over the place.
So if you know you'll only have actors which do not pass messages around (that is, they process them by themselves), then I guess you'll be just fine without a supertype for them.
I guess the reason that people do this more or less by default is that if you later change your code you don't have to create the trait afterwards, because you already did in the beginning.
Personally, I always try to avoid unnecessary overhead, so I'd probably not define a supertype unless I really need it. Also, I really don't know if creating a supertype has any effect on performance at all, but I'd be interesting to know.
Upvotes: 5
Reputation: 346
This is not mandatory but it is an OO design stuff. It is a better design to have an abstract type for you application domain messages. So you can have polymorphism benefits when dealing with Messages in our application code.
trait Message
object Ping extends Message
objet Pong extends Message
object Stop
For example if somewhere in your application you have to deal with bunch of messages regardless of their specific types (Ping or Pong) you will treat them all as objects of type Message. It makes sense? No ?
Upvotes: 0