2012-10-05 11 views

risposta

16

È possibile, dare un'occhiata a Akka Actor "ask" and "Await" with TimeoutException. Ma tieni presente che bloccare un attore è una pessima idea, perché durante quel periodo l'attore non può gestire nessun altro messaggio. Inoltre blocca un thread di elaborazione Akka.

Un approccio migliore consiste nell'inviare un messaggio (incendio e dimenticare) e pianificare un evento di timeout utilizzando Akka scheduler. Quando arriva la risposta, cancella quell'evento o imposta un contrassegno in modo che non si inneschi se la risposta arriva effettivamente in tempo.

+2

+1 per il programma soluzione. – paradigmatic

4

Potrebbe essere eccessivo, ma è possibile controllare il tratto Finite State Machine (FSM).

import akka._ 
import actor._ 
import util._ 
import duration._ 
import Impatient._ 

object Impatient { 
    sealed trait State 
    case object WaitingForMessage extends State 
    case object MessageReceived extends State 
    case object TimeoutExpired extends State 

    sealed trait Data 
    case object Unitialized extends Data 

    // In 
    case object Message 
} 

class Impatient(receiver: ActorRef) extends Actor with FSM[State, Data] { 
    startWith(WaitingForMessage, Unitialized) 

    when(WaitingForMessage, stateTimeout = 3 seconds) { 
    case Event(StateTimeout, data) => goto(TimeoutExpired) using data // data is usually modified here 
    case Event(Message, data) => goto(MessageReceived) using data // data is usually modified here 
    } 

    onTransition { 
    case WaitingForMessage -> MessageReceived => stateData match { 
     case data => log.info("Received message: " + data) 
    } 
    case WaitingForMessage -> TimeoutExpired => receiver ! TimeoutExpired 
    } 

    when(MessageReceived) { 
    case _ => stay 
    } 

    when(TimeoutExpired) { 
    case _ => stay 
    } 

    initialize 
} 

Qui è in azione:

object Main extends App { 
    import akka._ 
    import actor._ 
    import Impatient._ 

    val system = ActorSystem("System") 

    val receiver = system.actorOf(Props(new Actor with ActorLogging { 
    def receive = { 
     case TimeoutExpired => log.warning("Timeout expired") 
    } 
    })) 

    val impatient = system.actorOf(Props(new Impatient(receiver)), name = "Impatient") 
    impatient ! Message 

    val impatient2 = system.actorOf(Props(new Impatient(receiver)), name = "Impatient2") 
    Thread.sleep(4000) 
    impatient2 ! Message 

    system.shutdown() 
} 
Problemi correlati