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?
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With