views:

101

answers:

2

I'm trying to make an actor 'go to sleep' waiting for another actors signal. I want to do something like:

def act(){
    loop{ //Should I use loop here too??
        if(sleepy){
            react{
                   //SLEEPING
                    case "Wake Up"=> sleepy=false; //just to breack the react
            }
        }else{
            react{
                 //React to other messages
            }
        }
    }
}

Now, what happends with other messages when my actor is sleeping? do they get discarted? I don't want to lose them. What is a good way to fix this?

+5  A: 

You could use a guard on the other cases in the react block, unmatched messages in the react block are held in the actor's message queue. Be cautious that the actor will definitely be "woken" before the queue size is excessive.

If I remember correctly, you can only have one react block in the loop due to the design of react.

val receiver = new Actor {
  private var sleeping = true

  def act {
    loop {
      react {
        case "Wake Up"       => println("waking up"); sleeping = false
        case x if ! sleeping => println("processing "+x)
      }
    }
  }
}

receiver.start

import Thread.sleep

receiver ! "Message 1"
sleep(2000L)
receiver ! "Message 2"
sleep(2000L)
receiver ! "Wake Up"
sleep(2000L)
receiver ! "Message 3"
sleep(2000L)
receiver ! "Message 4"

waking up processing Message 1 processing Message 2 processing Message 3 processing Message 4

Don Mackenzie
+3  A: 

You can use a similar mechanism to Don but take advantage of the andThen functionality provided by Actor.Body:

def waitForSignal : () => Unit = react { case Signal(_) => }

def processMessages : () => Unit = loop { 
  react {
      case x => //process
  }
}

def act() = waitForSignal andThen processMessages

The reason for the explicit return type declaration () => Unit is because react never terminates normally (i.e. it returns Nothing). Nothing is at the bottom of the type hierarchy and a valid subtype of any other type.

I'm taking advantage of the implicit conversion from a () => Unit to the Body class which contains the andThen method.

oxbow_lakes