2

我想让一个演员睡一会儿,具体来说它应该根据一个条件决定是否自己睡:

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) 在演员内部打电话不是一件好事,应该有另一种方式。因此,我如何让它睡觉?

4

1 回答 1

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
  }
}

注意:我没有测试过这段代码!不过,应该给你一些想法。

于 2013-10-30T05:59:23.177 回答