2010-07-15 46 views
5

我試圖讓一個演員'去睡覺'等待另一個演員的信號。我想做的事情如下:如何讓一個斯卡拉演員'等待信號',但不要丟失任何消息?

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 
      } 
     } 
    } 
} 

現在,當我的演員睡覺時發生了什麼與其他消息?他們會不會放棄?我不想失去他們。什麼是解決這個問題的好方法?

回答

6

您可以在反應區塊中的其他情況下使用警衛,反應區塊中的未匹配消息保存在參與者的消息隊列中。請小心,在隊列大小過多之前,演員一定會「醒來」。

如果我沒有記錯,由於反應的設計,您只能在迴路中有一個反應塊。

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" 

醒來 處理消息1 處理消息2 處理消息3 處理消息4

6

可以使用類似的機制,以唐但利用由Actor.Body提供的andThen功能優點:

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

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

def act() = waitForSignal andThen processMessages 

顯式返回類型聲明的原因() => Unit是因爲react從不終止正常(即它返回Nothing)。 Nothing位於類型層次結構的底部,並且是任何其他類型的有效子類型。

我利用從() => UnitBody類的隱式轉換,其中包含andThen方法。