Fel*_*ers 28 scala scheduler akka
我希望有可能让演员入睡一会儿.演员应该决定自己要睡多久.由于Thread.sleep()不是推荐的方法,我想在akka中使用调度程序.因此我定义了一个演员是另一个演员可以注册被唤醒.
class Scheduler extends Actor {
def receive = {
case Sleep(duration) => context.system.scheduler.scheduleOnce(duration) {
sender ! Ring
}
}
}
Run Code Online (Sandbox Code Playgroud)
但发送方从不接收Ring消息.所以我的问题是
Rol*_*uhn 44
让我首先回答标题问题:是的,可以在actor中使用调度程序.
case Sleep(duration) =>
context.system.scheduler.scheduleOnce(duration, self, Ring)
Run Code Online (Sandbox Code Playgroud)
你没有说出你真正想要实现的目标,所以我在这里做了一个有根据的猜测,你想让演员通常做一些叫做"X"的事情 - 做一段叫做"Y"的事情,暂停"X" "活动.完整的解决方案是
class Sleepy extends Actor {
def receive = {
... // cases doing “X”
case Sleep(duration) =>
case object WakeUp
context.system.scheduler.scheduleOnce(duration, self, WakeUp)
context.become({
case WakeUp => context.unbecome()
// drop the rest
}, discardOld = false)
}
}
Run Code Online (Sandbox Code Playgroud)
使用FSM特性并在正常状态和睡眠状态之间切换也可以实现相同的效果.当然,你可以在睡觉时做任何你想做的事情,例如混合StashAkka 2.1 中的特性,并stash()在睡觉时,unstashAll()在收到WakeUp消息时呼叫所有(或一些)消息; 或者你可以完全做其他事情.演员非常灵活.
演员从不真正睡觉,他们总是处理传入的消息.如上所示,您可以定义这意味着什么,但基本原则是您不能挂起actor,以便它不会处理其邮箱中的消息.
Rya*_*pte 16
您正在关闭传递给调度程序的闭包中的"sender".这意味着Ring消息很可能被发送给错误的actor.你应该这样做:
case Sleep(duration) =>
val s = sender
context.system.scheduler.scheduleOnce(duration) {
s ! Ring
}
}
Run Code Online (Sandbox Code Playgroud)