Question

I have 2 actors, actor A send messages to actor B. Actor B then should process these numbers and print them on the same line

My code:

class ActorB extends Actor{
  def receive = {
     case 0 => println("0")
     case x : Int => println (x)
  }
}

but won't compile

Was it helpful?

Solution 2

You could do something like this (totally untested):

class ActorB extends Actor with ActorLogging {

  def receive = {
    case x : Int => context.become(waitingForMore(List(x)))
  }

  def waitingForMore(xs : List[Int]) : Receive = {
    case x : Int if(xs.size == 2) => 
      printResults(x :: xs)
      context.become(receive)

    case x : Int => context.become(waitingForMore(x :: xs))    
  }

  def printResults(xs : List[Int]): Unit = {
    // Do printing here.
  }
}

In this model, you would take advantage of the fact that Actors can alter their own internal behavior. You wouldn't be explicitly storing a list of Ints, but instead you would be passing it from function to function. Essentially the actor waits around for you to send it an Int (the receive method) and then enters a state where it gathers more results (the waitingForMore method). Once that method has gathered enough, it prints the results and returns back into the receive method, which starts the process all over again.

Edit As suggested, I'll just add a small comment as to why I proposed this model. I feel like the state your actor is in is more clearly modeled with this. As the problem grows and gets more complicated, this might be a good pattern to have in your head. Or it might not, as Felix pointed out both of these solutions get to the same answer through different ways. You should absolutely feel free to pick whichever solution you feel more comfortable with. My intent in showing this was to demonstrate an alternate approach that is more functional, that's all.

OTHER TIPS

You could do something like this:

class ActorB extends Actor with ActorLogging{
  var xs:List[Int] = Nil
  def receive = {
     case x : Int => 
        xs = x :: xs
        if(xs.length==3){
           println(xs.mkString(" ")+" avg: "+xs.sum/3d)
           xs = Nil
        }
  }
}

(I didn't test the above, but it should give you the idea)

I think this may be a bit easier than to use become/unbecome. Is there a reason you want to use that pattern instead maybe?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top