如何打印akka系统中的所有演员?

Che*_*rry 16 debugging scala akka

我创建了akka系统.假设其中有一些演员.我如何用他们的路径打印akka系统中的所有演员?(用于调试目的)

Chr*_*tin 14

Roland Kuhn的回复表明,这不是一个完全无关紧要的问题,但是你可以使用所有参与者都遵守的Identify-ActorIdentity请求 - 响应协议,非常接近(对于将在合理时间内回复消息的演员).

一些未经测试的代码拼凑在一起以说明这个想法:

import akka.actor._

def receive = {
    case 'listActors =>
      context.actorSelection("/user/*") ! Identify()

    case path: ActorPath =>
      context.actorSelection(path / "*") ! Identify()

    case ActorIdentity(_, Some(ref)) =>
      log.info("Got actor " + ref.path.toString)
      self ! ref.path
}
Run Code Online (Sandbox Code Playgroud)


zel*_*lla 8

ActorSystem有私有方法printTree,可用于调试.

1)私人方法呼叫者(来自https://gist.github.com/jorgeortiz85/908035):

class PrivateMethodCaller(x: AnyRef, methodName: String) {
  def apply(_args: Any*): Any = {
    val args = _args.map(_.asInstanceOf[AnyRef])

    def _parents: Stream[Class[_]] = Stream(x.getClass) #::: _parents.map(_.getSuperclass)

    val parents = _parents.takeWhile(_ != null).toList
    val methods = parents.flatMap(_.getDeclaredMethods)
    val method = methods.find(_.getName == methodName).getOrElse(throw new IllegalArgumentException("Method " + methodName + " not found"))
    method.setAccessible(true)
    method.invoke(x, args: _*)
  }
}

class PrivateMethodExposer(x: AnyRef) {
  def apply(method: scala.Symbol): PrivateMethodCaller = new PrivateMethodCaller(x, method.name)
}
Run Code Online (Sandbox Code Playgroud)

2)用法

val res = new PrivateMethodExposer(system)('printTree)()
println(res)
Run Code Online (Sandbox Code Playgroud)

将打印:

-> / LocalActorRefProvider$$anon$1 class akka.actor.LocalActorRefProvider$Guardian status=0 2 children
   ?-> system LocalActorRef class akka.actor.LocalActorRefProvider$SystemGuardian status=0 3 children
   |   ?-> deadLetterListener RepointableActorRef class akka.event.DeadLetterListener status=0 no children
   |   ?-> eventStreamUnsubscriber-1 RepointableActorRef class akka.event.EventStreamUnsubscriber status=0 no children
   |   ?-> log1-Logging$DefaultLogger RepointableActorRef class akka.event.Logging$DefaultLogger status=0 no children
   ?-> user LocalActorRef class akka.actor.LocalActorRefProvider$Guardian status=0 1 children
...
Run Code Online (Sandbox Code Playgroud)

当心,它可以导致OOM如果你有很多演员.