【发布时间】:2014-04-08 14:32:54
【问题描述】:
在对 Akka 演员进行试验时,我设计了一个与预期不太相符的用例。我定义了一个演员,MyActor,它接收"start" 消息。此消息启动一个调度程序,该调度程序应将消息"request" 转发给它self 每1 second。代码如下:
import akka.actor._
import scala.concurrent.Await
import scala.concurrent.duration._
import akka.pattern.gracefulStop
import scala.concurrent.ExecutionContext.Implicits.global
object ScheduledActors {
def main(args: Array[String]) {
implicit val system = ActorSystem("ScheduledActors")
val admin = system.actorOf(Props[MyActor], name = "my-actor")
admin ! "start"
val adminFuture = gracefulStop(admin, 2 minutes)
Await.result(adminFuture, 2 minutes)
}
class MyActor extends Actor {
var cancellableOption: Option[Cancellable] = None
def receive = {
case "start" =>
println("start")
cancellableOption =
Some(context.system.scheduler.schedule(0 seconds, 1 second) { self ! "request" })
case "request" =>
println("request")
case "stop" =>
println("stop")
cancellableOption match {
case None => // no-op
case Some(v) => v.cancel()
}
context.stop(self)
}
}
}
我尝试了几种变体。利用带有显式ActorRef 和message 的schedule 方法变体。例如:
schedule(initialDelay: Duration, frequency: Duration, receiver: ActorRef, message: Any): Cancellable
在每种情况下,"request" 消息似乎从未被参与者收到。该块肯定被称为,因为我已经使用println 语句作为健全性检查进行了验证。但是送货是不行的。
这让我想到self 引用在此上下文中实际执行时可能不会提供相同的上下文(à la ForkJoinPool 调用)。 Akka 文档确实警告不要在调度调用的上下文中使用不稳定的引用。然而,self 作为接收者被明确引用为reasonable alternative。
在这一点上,我有点不知所措。任何帮助是极大的赞赏。
【问题讨论】: