How do I create a unique identifier for an Actor?

Suppose I have an application that uses Actors to process a User. Thus, there is one UserActor for each user. Also, each user Actor is associated with a user through an identifier, for example. to handle actions with a specific user, you should get an Actor like this:

 ActorSelection actor = actorSystem.actorSelection("/user/1");

      

where 1 is the user ID.

So the problem is how to efficiently generate a unique ID within the cluster? First you need to check that the new identifier will not duplicate the existing one. I can create one actor to generate id that will live in one node, and the id is requested before any new UserActor Generator is created, but this results in an additional request within the cluster whenever a user is created. Is there a way to make this more efficient? Are there built-in akka methods for this?

PS While this architecture is ineffective for using Actor, any suggestion / best practice is appreciated.

+3


source to share


3 answers


I won't say if your approach is a good idea. It will be up to you to decide. If I understand your problem correctly, I can suggest a high level approach to get you to work for you. If I understand correctly, you have a cluster and for any given userId there must be an actor on the system that handles requests for it, and it must be on only one node and constantly reachable based on the user id of the user. If this is correct, then consider the following approach.

Start over with a simple actor, call him UserRequestForwarder

. This task of actors is to find an instance of an actor to request a specific user id and navigate to it. If this actor instance does not already exist, then this actor will create it before sending it to it. A very rough sketch might look like this:

class UserRequestForwarder extends Actor{
  def receive = {
    case req @ DoSomethingForUser(userId) =>
      val childName = s"user-request-handler-$userId"
      val child = context.child(childName).getOrElse(context.actorOf(Props[UserRequestHandler]))
      child forward req
  }
}

      



This actor will now be deployed to every node in the cluster via the ConsistentHashingPool router, configured to have one instance per node. You just need to make sure there is something in every request that has to go through that router that allows it to sequentially hash the node that is processing requests for that user (hopefully using a user id)

So, if you pass all requests through this router, they will always land on the node that is responsible for that user, ending up in UserRequestForwarder

, which will then find the correct user actor on that node and pass the request to it.

I haven't tried this approach myself, but it might work for what you are trying to do if I understood your problem correctly.

+4


source


Not an akka expert, so I can't suggest the code, but the following approach shouldn't work:

Let one actor be responsible for creating the actors. And let him keep the names of the hash actors for the actors he created, and this is not dead.



If you need to distribute the load among several participants, you can submit a task based on the first n digits of the hashcode of the name of the actor to be created.

+1


source


You seem to have an answer for how to generate a unique id. As for your larger question, this is what the Akka cluster cluster solves. It will handle distributing the skull between your cluster, finding or launching your members in the cluster, and even rebalancing.

http://doc.akka.io/docs/akka/2.3.5/contrib/cluster-sharding.html

There is also an activator with a really good example.

http://typesafe.com/activator/template/akka-cluster-sharding-scala

+1


source







All Articles