Tracking Akka when actors have finished

I have the following code that goes through a list of people and calls a callback for each of them in class1.

def syncPeople(callback: Person => _) = Future {
   person.findAll(criteria).foldLeft(0L) { (count, obj) =>
      callback(obj)
      count + 1
   } 
}

      

The callback and call to syncPeople is in class2 and looks similar to this

def getActor(person: Person):ActorRef = {
  if(person.isMale) maleActor
  else femaleActor
}

def process(person: Person): Unit = {
   val workActor = getActor(person)
   workActor ! person
} //The actor does the actual work and may be quite intense

def syncPeople(process)

      

Now I want to track the total time it takes to sync all people. those. when the last workActor exits. I am using a third actor: MonitorActor to keep track of the start and end times. MaleActor, FemaleActor can send messages to this when they process an individual

What is the best way to track these unresolved processes?

I researched

  • Future.sequence // but the class dispatching workActor is not an actor. so the future doesn't receive the message

  • keeping track of personIds when they run out, but without using var to accumulate received messages in MonitorActor, it is impossible to implement this .. and using var is not the preferred way of doing things

What could be other ways to implement this

0


source to share


2 answers


Funny, I am working on the same problem at the moment. The solution I would suggest is using akka-fsm which keeps track of the state.

Essentially, in something outside of your state object, do something like create a Long that represents id:

def getId(): Long = System.currentTimeMillis() / 1000L

      



The state object, if properly implemented, is immutable, so you just keep reusing that identifier throughout the transaction.

I know this answer is missing a lot of implementation details, but I am still working on the implementation myself in my own code. Hopefully after some reading about akka-fsm and playing with it, this answer makes sense?

+4


source


Don't daemonize mutable state, it's SHARED mutable state that causes most problems. You don't have a shared mutable state inside the actor because you are always talking to actorRefs and the actors only process one message at a time (no race conditions or other evil things). What I'm saying is ok to use var

(unless you create some futures inside the actor that mutate var

because then you are back to the mutable SHARING state). FSM is another solution suggested by @devnulled, but it looks more like an overkill case for your use.



+1


source







All Articles