Akkaシステムを作成しました。その中に何人かの俳優がいるとしましょう。 akkaシステムのすべてのアクターをパスとともに印刷するにはどうすればよいですか? (デバッグ目的)
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
}
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)
}
2)使用法
val res = new PrivateMethodExposer(system)('printTree)()
println(res)
印刷します:
-> / 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
...
アクターが多い場合は、OOMが発生する可能性があることに注意してください。
ドキュメント によると、ワイルドカードを使用してActorSelection
を使用できます*
アクターに識別メッセージを送信させる。 ActorRef
sを収集するアクターを持つことができます。
@ chris-martinが述べたように、現在忙しくないアクターのみが送信します。非常に単純な俳優:
// make all the available actor to send an identifying message
public void freeActors()
{
ActorSelection selection =
getContext().actorSelection("/user/*");
selection.tell(new Identify(identifyId), getSelf());
}
...
// collect responses
@Override
public void onReceive(Object message) {
if (message instanceof ActorIdentity) {
ActorIdentity identity = (ActorIdentity) message;
// get the ref of the sender
ActorRef ref = identity.getRef();
// the sender is up and available
...
編集:これはJava用であることは知っていますが、私には役立つようでした。