Это хороший вариант использования для 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)
}
}
После каждого сообщения, актер будет регистрировать время, затрачиваемое до сих пор. Конечно, если вы хотите сделать что-то еще с этой переменной, вам придется адаптировать это.
Этот подход не измеряет время, в течение которого актер жив, и только время, затрачиваемое на обработку сообщений. Не будет и точной, если ваша функция получения создаст будущее.