メッセージを受信するActor
まで X 秒待機し、メッセージを受信した場合は通常どおり処理し、それ以外の場合は別のメッセージActor
(コンストラクターで事前に決定) を送信することはできますか?
質問する
13660 次
3 に答える
18
可能です。Akka Actor の「ask」と「Await」を TimeoutException で確認してください。ただし、アクター内でブロックすることは非常に悪い考えであることに注意してください。その間、アクターは他のメッセージを処理できないからです。さらに、1 つの Akka 処理スレッドをブロックします。
より良いアプローチは、メッセージを送信し (ファイア アンド フォーゲット)、 Akka スケジューラを使用してタイムアウト イベントをスケジュールすることです。応答が到着したら、そのイベントをキャンセルするか、何らかのフラグを設定して、応答が実際に時間どおりに到着した場合にトリガーされないようにします。
于 2012-10-05T06:46:29.033 に答える
5
はい、メッセージを待ちたい場合は、単純にreceiveTimeoutを設定します: http://doc.akka.io/docs/akka/current/scala/actors.html#receive-timeout
(ドキュメントはここで少し誤解を招きます。すべてのメッセージの後に receiveTimeout を設定することもできます)
于 2012-10-05T21:07:18.357 に答える
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()
}
于 2012-10-05T07:25:03.123 に答える