我想让一个演员睡一会儿,特别是它应该根据条件决定是否要自己:
class MyActor extends Actor {
def receive {
case "doWork" => doWork()
}
def doWork(): Unit = {
// doing some work
val condition = calculateCondition
if (condition) {
// sleep for 5 seconds
// Thread.sleep(5000)
}
}
}
我非常确定在演员中调用Thread.sleep(5000)
并不应该是另一种方式。因此,我该如何让它睡觉?
答案 0 :(得分:8)
我希望使用Actor的状态/行为更改来执行此操作。 Akka为您提供了两种方法:您可以实现一个完整的状态机,或者使用context.become
(并混合在akka.actor.Stash
中),并让actor传递(调度)消息对自己。对于这种情况,前者感觉有些过分,所以这就是我要编写代码的方式:
import akka.actor._
import scala.concurrent.duration._
class MySleepyActor(duration: FiniteDuration = (5 seconds)) extends Actor with Stash {
import context._
override def preStart() { become(running) }
def receive = PartialFunction.empty
def running: Actor.Receive = {
case "doWork" =>
if (doWork()) {
scheduleReactivate
become(paused)
}
case "wakeUp" => // already awake
}
def paused: Actor.Receive = {
case "doWork" => stash()
case "wakeUp" =>
unstashAll()
become(running)
}
def scheduleReactivate: Unit = {
system.scheduler.scheduleOnce(duration, self, "wakeUp")
}
def doWork(): Boolean = {
// doing some work, then:
calculateCondition
}
}
注意:我没有测试过这段代码!但是,应该给你一些合意的想法。