t-rex-50
t-rex-50

Reputation: 231

Akka actors and messages best practic

I'm trying to understand the tradeoffs and best practices (if there are) between the following options:

Messages

  1. Many messages classes (e.g. MessageClassForActorA, MessageClassForActorB, MessageClassForActorC....) where every class has only the spesific fields that the target actor needs.
  2. The above option were all the MessagesClass extends a basic class where some of the duplicated fields are stored.
  3. One message class (e.g. MotherOfAllMessages) that contians all the fields that every actor in the system may need. Every actor in its turn uses (get / set) only the relevant fields out of this message

Actors

  1. Actor can get meny messages types and the business logic is split accordingly

.match(POJOA.class, message -> {

...

.match(POJOB.class, message -> {

...

.match(POJOC.class, message -> { ...

  1. Actor recieves only one message type and do all the different business logic according to some ENUM / parameter within the message

if (POJO.getPhase().equals("start"))

...

else ...

What is the common practice to use? What is better in turms of performance, code maintanability etc.

Upvotes: 0

Views: 230

Answers (1)

Diego Martinoia
Diego Martinoia

Reputation: 4652

A mixture of A, B and C has worked very well for me so far. You want your messages as specific as you can (so they are self-explanatory), but you still need some generality.

For example: suppose you are using your actors as a key-value store.

You can have some generic Get/Set/Delete messages

public class Get {String key;}
public class Set<T> {String key; T value;}
public class Delete {String key;}

The issue is your Set message. It's type parametric. Some serialization frameworks do not make that easy on you.

So you can change it to specific sets:

public class SetA {String key; A value;}
public class SetB {String key; B value;}

And bam, the type parameter is gone.

But the 3rd option is something you still need! Akka serialization requires you to bind a serializer to a class (the top level one), and in most cases you want to use a single serializer for all your messages, so the way to go for that is an empty interace:

public interface Message {}
public class Get implements Message {String key;}
public class SetA implements Message {String key; A value;}
public class SetB implements Message {String key; B value;}
public class Delete implements Message {String key;}

And then in your config file:

akka.actor{
  serializers {
    mySerializer = xxx
  }
  serialization-bindings {
    Message = mySerializer
  }
}

Upvotes: 0

Related Questions