2012-10-05 13 views

Respuesta

16

Es posible, eche un vistazo a Akka Actor "ask" and "Await" with TimeoutException. Pero tenga en cuenta que bloquear dentro de un actor es una muy mala idea ya que durante ese tiempo el actor no puede manejar ningún otro mensaje. Además, bloquea un hilo de procesamiento Akka.

Un mejor enfoque es enviar un mensaje (fuego y olvidar) y programar algún evento de tiempo de espera usando Akka scheduler. Cuando llegue la respuesta, cancele ese evento o establezca un indicador para que no se active si la respuesta llegó a tiempo.

+2

+1 para el horario r solución. – paradigmatic

4

Podría ser una exageración, pero podría verificar el rasgo 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 
} 

Aquí está en acción:

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() 
} 
Cuestiones relacionadas