2010-07-15 10 views
5

Estoy tratando de hacer que un actor 'se vaya a dormir' esperando la señal de otro actor. Quiero hacer algo como:¿Cómo hacer que un actor scala 'espere la señal' pero no pierda ningún mensaje?

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

Ahora, ¿qué pasa con otros mensajes cuando mi actor está durmiendo? ¿Se discartan? No quiero perderlos. ¿Cuál es una buena manera de arreglar esto?

Respuesta

6

Puede usar un protector en los otros casos en el bloque de reacción, los mensajes no coincidentes en el bloque de reacción se mantienen en la cola de mensajes del actor. Tenga cuidado de que el actor definitivamente será "despertado" antes de que el tamaño de la cola sea excesivo.

Si no recuerdo mal, solo puede haber un bloque de reacción en el circuito debido al diseño de la reacción.

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" 

despertar Procesamiento de mensajes 1 Procesamiento de mensajes 2 Procesamiento de mensajes 3 Procesamiento de mensajes 4

6

Se puede utilizar un mecanismo similar a Don pero tomar ventaja de la funcionalidad andThen proporcionada por Actor.Body:

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

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

def act() = waitForSignal andThen processMessages 

Motivo de la declaración del tipo de declaración explícita () => Unit es porque react nunca termina normalmente (es decir devuelve Nothing). Nothing se encuentra en la parte inferior de la jerarquía de tipos y un subtipo válido de cualquier otro tipo.

Aprovechando la conversión implícita de () => Unit a la clase Body que contiene el método andThen.

Cuestiones relacionadas