scala Akka Actor - 等待一段时间等待消息,否则发送消息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12740792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Akka Actor - wait for some time to expect a message, otherwise send a message out
提问by adelbertc
Is it possible to make an Actorwait for X amount of seconds to receive any message, and if a message is received, process it as usual, otherwise send a message to some other Actor(pre-determined in the constructor)?
是否可以Actor等待 X 秒来接收任何消息,如果收到消息,则照常处理它,否则将消息发送给其他人Actor(在构造函数中预先确定)?
采纳答案by Viktor Klang
Yes, if you want to wait for anymessage, you simply set a receiveTimeout: http://doc.akka.io/docs/akka/current/scala/actors.html#receive-timeout
是的,如果你想等待任何消息,你只需设置一个receiveTimeout:http: //doc.akka.io/docs/akka/current/scala/actors.html#receive-timeout
(The docs is slightly misleading here, you can set the receiveTimeout after every message also)
(这里的文档有点误导,您也可以在每条消息后设置 receiveTimeout)
回答by Tomasz Nurkiewicz
It's possible, have a look at Akka Actor "ask" and "Await" with TimeoutException. But keep in mind that blocking inside an actor is a very bad idea since during that time actor can't handle any other messages. Moreover it blocks one Akka processing thread.
有可能,用 TimeoutException看看Akka Actor“ask”和“Await”。但是请记住,在actor 内部阻塞是一个非常糟糕的主意,因为在此期间actor 无法处理任何其他消息。此外,它阻塞了一个 Akka 处理线程。
A better approach is to send a message (fire and forget) and schedule some timeout event using Akka scheduler. When the response arrives, cancel that event or set some flag so that it won't trigger if the reply actually came on time.
更好的方法是发送消息(即发即忘)并使用Akka 调度程序安排一些超时事件。当响应到达时,取消该事件或设置一些标志,以便在响应确实准时到达时它不会触发。
回答by agilesteel
Might be an overkill, but you might check out the Finite State Machine (FSM)trait.
可能有点矫枉过正,但您可以查看有限状态机 (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
}
Here it is in action:
这是在行动:
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()
}

