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