Akka演员 - 等待一段时间来发送消息,否则发送消息

时间:2012-10-05 06:34:00

标签: scala akka actor

是否可以让Actor等待X秒数来接收任何消息,如果收到消息,则照常处理,否则向其他Actor发送消息(在构造函数中预先确定的?)

3 个答案:

答案 0 :(得分:17)

有可能,看看Akka Actor "ask" and "Await" with TimeoutException。但请记住,阻止演员内部是一个非常糟糕的主意,因为在那段时间演员不能处理任何其他消息。此外,它阻止了一个Akka处理线程。

更好的方法是发送消息( fire and forget )并使用Akka scheduler安排一些超时事件。当响应到达时,取消该事件或设置一些标志,以便在答复实际到达时不会触发。

答案 1 :(得分:4)

可能有点矫枉过正,但您可能会查看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
}

这是在行动:

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

答案 2 :(得分:3)

是的,如果您要等待任何消息,只需设置 receiveTimeout http://doc.akka.io/docs/akka/current/scala/actors.html#receive-timeout

(这里的文档略有误导,您也可以在每条消息后设置receiveTimeout)