Search code examples
javascalakubernetesakkaakka-supervision

Is this a correct use case for an Akka role?


I'm updating an Akka cluster where a particular actor should start on a node within the cluster depending on a configuration value. Initially, I considered using a custom Akka cluster role and have did some research, reading https://doc.akka.io/docs/akka/current/cluster-usage.html

offers this code :

      void register(Member member) {
        if (member.hasRole("frontend"))
          getContext()
              .actorSelection(member.address() + "/user/frontend")
              .tell(BACKEND_REGISTRATION, getSelf());
      }

So I could use something like : if (member.hasRole("<MY_CUSTOM_ROLE>")) {
    //Start My Actor
}

Starting an actor depending on it's role does not appear to be the intended function of roles in Akka classic as in the example above the actor is not created. Instead a message is passed to another actor based on the path. As the spawn method is not available in Akka classic, creating an actor based on a role is not achievable for Akka classic?

Akka typed for roles appears to achieve the expected functionality I'm trying to implement:

From https://doc.akka.io/docs/akka/current/typed/cluster.html :

Member selfMember = Cluster.get(context.getSystem()).selfMember();

if (selfMember.hasRole("backend")) {
  context.spawn(Backend.create(), "back");
} else if (selfMember.hasRole("front")) {
  context.spawn(Frontend.create(), "front");
}

Here an Akka actor is created if the role is available.

As I'm using classic Actors I'm considering adding an environment variable instead of an Akka "role" for each deployment in the .yml file, then within the source code that starts all Akka actors if the environment variable is populated for the given deployment start the given actor, otherwise do not start the actor. Is this a viable solution for determining which actor should be started on each node within the cluster ?


Solution

  • In Akka Classic, you would have something like

    if (member.hasRole("<MY CUSTOM ROLE>")) {
      Props props = ...
      ActorRef ref = context.system().actorOf(props, "special-name") // spawn as a direct child of the ActorSystem
      // or ...
      ActorRef ref = context.actorOf(props, "special-name") // spawn as a child of this actor
    }
    

    In Classic, you can directly spawn through the ActorSystem.