我有一套Akka Actors,我给每一个提供了几百条消息。我想跟踪该Actor的每个实例处理它收到的所有消息所花费的时间。我目前正在做的是在Actor实例中有一个状态:
var startTime
var firstCall
首次调用Actor实例时,我设置了两个变量。有没有其他方法可以用来跟踪我的Actor实例的处理时间?我想避免在我的Actor实例中有一个本地状态。
答案 0 :(得分:4)
这是context.become
的一个很好的用例。
请记住,Akka演员中的接收块只是PartialFunction[Any, Unit]
,所以我们可以将其包含在另一个部分函数中。这与Akka的内置LoggingReceive采用的方法相同。
class TimingReceive(r: Receive, totalTime: Long)(implicit ctx: ActorContext) extends Receive {
def isDefinedAt(o: Any): Boolean = {
r.isDefinedAt(o)
}
def apply(o: Any): Unit = {
val startTime = System.nanoTime
r(o)
val newTotal = totalTime + (System.nanoTime - startTime)
log.debug("Total time so far: " + totalTime + " nanoseconds")
ctx.become(new TimingReceive(r, newTotal))
}
}
object TimingReceive {
def apply(r: Receive)(implicit ctx: ActorContext): Receive = new TimingReceive(r, 0)
}
然后你可以像这样使用它:
class FooActor extends Actor {
def receive = TimingReceive {
case x: String => println("got " + x)
}
}
在每条消息之后,actor将记录到目前为止所用的时间。当然,如果您想对该变量做其他事情,您将不得不对此进行调整。
这种方法当然不衡量演员活着的时间,只测量实际处理消息所花费的时间。如果你的接收功能创造了未来,它也不会准确。