我正在尝试使用scala中的akka。在主scala线程中,我想启动一个akka actor,向它发送一条消息,并阻塞直到该actor终止。做这个的最好方式是什么?
例如,我有一个测试演员只是反复向自己发送消息:
class Incrementer() extends Actor {
val maxMessages = 5
var counter = 0
def receive() = {
case DoIncr() => {
if (counter < maxMessages) {
counter += 1
self ! DoIncr()
} else {
self.stop()
}
}
}
}
并通过以下方式调用:
val inc = actorOf(new Incrementer()).start()
val result = inc !! DoIncr()
println(result) // this should block this thread, but it doesn't seem to.
// do other stuff
该块只需要超过5,000毫秒来执行而不是我期望的几毫秒,所以它似乎与默认的未来超时有关 - 并且程序实际上并未终止。我真正想做的就是发送x条消息的时间。这是怎么回事?
答案 0 :(得分:4)
正如Viktor所说,为了使!!
成功终止,您必须回复该消息。你看到演员默认超时的5秒延迟,这是可配置的。更多信息可以在Akka site找到。
如果您使用forward
发送邮件而不是!
,则self.reply
会回复原始发件人。
您发送给Akka actor的第一条消息会执行一些在处理其他消息时不会发生的设置。请务必将此考虑在内。
更正后的代码为:
import akka.actor._
object DoIncr
class Incrementer extends Actor {
val maxMessages = 5
var counter = 0
def receive = {
case DoIncr =>
if (counter < maxMessages) {
counter += 1
self forward DoIncr
} else {
self.reply(()) // replying with () since we have nothing better to say
self.stop()
}
}
}
除了:我做了一些其他更改,以使您的代码与惯用的Scala保持一致。您的代码在没有这些更改的情况下工作,但它现在看起来更像是典型的Scala代码。
object
。Actor
的{{1}}方法没有parens;你的实施班也不应该有它们。receive
语句的正文不需要大括号。