2010-07-15 11 views
5

Sto cercando di far addormentare un attore in attesa di un altro segnale di attori. Voglio fare qualcosa del tipo:Come fare un attore di scala 'attendere il segnale' ma non perdere nessun messaggio?

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

Ora, cosa succede con altri messaggi quando il mio attore dorme? vengono scartati? Non voglio perderli. Qual è un buon modo per risolvere questo problema?

risposta

6

È possibile utilizzare una protezione negli altri casi nel blocco di reazione, i messaggi non corrispondenti nel blocco di reazione sono trattenuti nella coda messaggi dell'attore. Siate cauti sul fatto che l'attore sarà sicuramente "svegliato" prima che la dimensione della coda sia eccessiva.

Se ricordo correttamente, è possibile avere un solo blocco di reazione nel loop a causa del disegno di reazione.

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" 

risveglio elaborazione dei messaggi 1 elaborazione Messaggio 2 elaborazione Messaggio 3 elaborazione dei messaggi 4

6

È possibile utilizzare un meccanismo simile a Don ma sfruttare la funzionalità andThen fornita da Actor.Body:

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

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

def act() = waitForSignal andThen processMessages 

Motivo della dichiarazione del tipo di reso esplicito () => Unit è perché react non termina mai normalmente (ad es. restituisce Nothing). Nothing si trova nella parte inferiore della gerarchia di tipi e un sottotipo valido di qualsiasi altro tipo.

Sto sfruttando la conversione implicita da () => Unit alla classe Body che contiene il metodo andThen.

Problemi correlati