Akka 2.2.0: Asking ActorSelection to Identify

2,397 views
Skip to first unread message

Ngoc Dao

unread,
Jul 13, 2013, 11:12:24 PM7/13/13
to akka...@googlegroups.com
I'm using Akka 2.2.0.
Can I do this to get ActorRef from ActorSelection?

val sel = context.actorSelection(escape(myActorName))
val futuresel.ask(Identify(None))(myTimeout).mapTo[ActorIdentity].map(_.ref)
val opt: Option[ActorRef] = Await.result(futuremyTimeout)

The above code always throw TimeoutException. Why?

Akka Team

unread,
Jul 15, 2013, 7:29:10 AM7/15/13
to Akka User List
Hi Ngoc

I just tried this and works fine:

      val echo = system.actorOf(Props(new Actor { def receive = { case x ⇒ sender ! x } }), "select-echo")
      val identityFuture = (system.actorSelection("/user/select-echo") ? Identify(None))
        .mapTo[ActorIdentity].map(_.ref.get)

      Await.result(identityFuture, 5 seconds) must be === echo

Are you sure that your actor exists, or your query string is correct?

-Endre


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Akka Team
Typesafe - The software stack for applications that scale
Blog: letitcrash.com
Twitter: @akkateam

Ngoc Dao

unread,
Jul 15, 2013, 10:04:54 AM7/15/13
to akka...@googlegroups.com
Endre,

Your code works in console. I guess I'm seeing the TimeoutException because I'm doing Await.result inside an actor.

More info:
Please see the log below ("xitrum" is my actor system). Why there are "[akka://xitrum/deadLetters] Message [akka.actor.ActorIdentity]" and "[akka://xitrum/deadLetters]"?


java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]
at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:96) ~[scala-library.jar:na]
at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:100) ~[scala-library.jar:na]
at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:107) ~[scala-library.jar:na]
at akka.dispatch.MonitorableThreadFactory$AkkaForkJoinWorkerThread$$anon$3.block(ThreadPoolBuilder.scala:169) ~[akka-actor_2.10-2.2.0.jar:2.2.0]
at scala.concurrent.forkjoin.ForkJoinPool.managedBlock(ForkJoinPool.java:3640) [scala-library.jar:na]
at akka.dispatch.MonitorableThreadFactory$AkkaForkJoinWorkerThread.blockOn(ThreadPoolBuilder.scala:167) ~[akka-actor_2.10-2.2.0.jar:2.2.0]
at scala.concurrent.Await$.result(package.scala:107) ~[scala-library.jar:na]
at xitrum.util.RemoteActorRegistry.xitrum$util$RemoteActorRegistry$$lookupLocal(ActorRegistry.scala:159) [xitrum_2.10.jar:2.7-SNAPSHOT]
at xitrum.util.RemoteActorRegistry.xitrum$util$RemoteActorRegistry$$lookupOrCreate(ActorRegistry.scala:222) [xitrum_2.10.jar:2.7-SNAPSHOT]
at xitrum.util.RemoteActorRegistry$$anonfun$receive$2.applyOrElse(ActorRegistry.scala:149) [xitrum_2.10.jar:2.7-SNAPSHOT]
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498) [akka-actor_2.10-2.2.0.jar:2.2.0]
at akka.actor.ActorCell.invoke(ActorCell.scala:456) [akka-actor_2.10-2.2.0.jar:2.2.0]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237) [akka-actor_2.10-2.2.0.jar:2.2.0]
at akka.dispatch.Mailbox.run(Mailbox.scala:219) [akka-actor_2.10-2.2.0.jar:2.2.0]
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386) [akka-actor_2.10-2.2.0.jar:2.2.0]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library.jar:na]

[INFO] [07/15/2013 22:31:29.113] [xitrum-akka.actor.default-dispatcher-12] [akka://xitrum/deadLetters] Message [akka.actor.ActorIdentity] from Actor[akka://xitrum/deadLetters] to Actor[akka://xitrum/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

Akka Team

unread,
Jul 16, 2013, 6:20:24 AM7/16/13
to Akka User List
Hi!


On Mon, Jul 15, 2013 at 4:04 PM, Ngoc Dao <ngocda...@gmail.com> wrote:
Endre,

Your code works in console. I guess I'm seeing the TimeoutException because I'm doing Await.result inside an actor.

You should not Await inside an actor ;)
 

More info:
Please see the log below ("xitrum" is my actor system). Why there are "[akka://xitrum/deadLetters] Message [akka.actor.ActorIdentity]" and "[akka://xitrum/deadLetters]"?

This is definitely suspicious, but I cannot reproduce it. Can you
 - show the pattern that you pass to system.actorSelection (i.e. the value of escape(myActorName) )
 - or even better, attach a small self-contained code that reproduces the problem

Then I can debug and see if it is a bug or suboptimal error reporting.

-Endre

Ngoc Dao

unread,
Jul 16, 2013, 11:08:42 PM7/16/13
to akka...@googlegroups.com
> You should not Await inside an actor ;)

Thanks for confirming.


> attach a small self-contained code that reproduces the problem

The error log belongs to the case when there's Await.result inside an actor. Await.result should not be there in the first place as I understand. Do you still want the sample code with Await.result inside an actor?

Akka Team

unread,
Jul 17, 2013, 5:08:00 AM7/17/13
to Akka User List
Hi Ngoc,


The error log belongs to the case when there's Await.result inside an actor. Await.result should not be there in the first place as I understand. Do you still want the sample code with Await.result inside an actor?

Await.result is bad practice but should not cause the TimeoutException here unless it is a deadlock, which I doubt. I just want to be sure what the problem is.

-Endre

Ngoc Dao

unread,
Jul 18, 2013, 2:55:21 AM7/18/13
to akka...@googlegroups.com
Endre,

This is the sample source code:
https://github.com/ngocdaothanh/await_actor

$ sbt run
[info] Loading project definition from /Users/ngocdt/src/await_actor/project
[info] Set current project to glokka (in build file:/Users/ngocdt/src/await_actor/)
[info] Running glokka.Main
[INFO] [07/18/2013 15:53:56.181] [glokka-akka.actor.default-dispatcher-3] [akka://glokka/user/glokka.LocalActorRegistry%24] ActorRegistry starting: Actor[akka://glokka/user/glokka.LocalActorRegistry%24#-177186834]
[ERROR] [07/18/2013 15:54:01.207] [glokka-akka.actor.default-dispatcher-3] [akka://glokka/user/glokka.LocalActorRegistry%24] Futures timed out after [5 seconds]

java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]
    at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:96)
    at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:100)
    at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:107)
    at akka.dispatch.MonitorableThreadFactory$AkkaForkJoinWorkerThread$$anon$3.block(ThreadPoolBuilder.scala:169)
    at scala.concurrent.forkjoin.ForkJoinPool.managedBlock(ForkJoinPool.java:3640)
    at akka.dispatch.MonitorableThreadFactory$AkkaForkJoinWorkerThread.blockOn(ThreadPoolBuilder.scala:167)
    at scala.concurrent.Await$.result(package.scala:107)
    at glokka.LocalActorRegistry$$anonfun$receive$1.applyOrElse(LocalActorRegistry.scala:29)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
    at akka.actor.ActorCell.invoke(ActorCell.scala:456)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
    at akka.dispatch.Mailbox.run(Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

[INFO] [07/18/2013 15:54:01.210] [glokka-akka.actor.default-dispatcher-3] [akka://glokka/user/glokka.LocalActorRegistry%24] ActorRegistry starting: Actor[akka://glokka/user/glokka.LocalActorRegistry%24#-177186834]
[INFO] [07/18/2013 15:54:01.215] [glokka-akka.actor.default-dispatcher-3] [akka://glokka/deadLetters] Message [akka.actor.ActorIdentity] from Actor[akka://glokka/deadLetters] to Actor[akka://glokka/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

Akka Team

unread,
Jul 19, 2013, 6:52:03 AM7/19/13
to Akka User List
Hi Ngoc!

I finally had some time, and I figured it out what went wrong. You actually did manage to deadlock your actor :)

The actor selection you tried to look up looks like the following:

  ActorSelection[Actor[akka://glokka/user/test#244828061]/nonexistent]

A selection consists of two parts, an anchor, which is a known actorref, and a path part that will be tried to be looked up. The Identify message travels down from the anchor through the matching children recursively* until it finds the matching child/children. In this case however the anchor is blocking on the result of the future, so it cannot process the Identify, and since it does not process the Identify, it waits until Timeout. At that point of course the Identify will be processed, but the result will be delivered to dead letters already.

[* sort-of, I simplified the story a bit]

You can try this by replacing
 
  context.actorSelection(escape(name))

to

  context.system.actorSelection(escape(name))

which changes the anchor to be the system ref itself, avoiding the deadlock.

Anyway, don't block your actors ;)

-Endre

vatel

unread,
Jul 21, 2013, 1:23:27 PM7/21/13
to akka...@googlegroups.com
Hi Endre,

is there some docs explaining (in more details):

a) routing/delivery logic when using ActorSelection - since the delivery
to ActorSelection is more complicated, is it slower (if compare to clean
ActorRef)?

b) implementation of Identify - does it mean that Identify message goes
through mailboxes of multiple actors (maybe internally without calling
"receive" method)?

--
Victor

Akka Team

unread,
Jul 22, 2013, 6:33:10 AM7/22/13
to Akka User List
Hi Victor,


is there some docs explaining (in more details):

Not really since they are internals, and we reserve the right to change how it works :) Generally an ActorSelection consists of an anchor part and a selection part, where the anchor is an ordinary ActorRef. The message you send to an ActorSelection will be wrapped in a SelectionPath message and will be delivered to the anchor. From the anchor it traverses down recursively according to the selection pattern and unfolding the wrapped message at a matching actor.
 

a) routing/delivery logic when using ActorSelection - since the delivery to ActorSelection is more complicated, is it slower (if compare to clean ActorRef)?

Yes it is slower somewhat.
 

b) implementation of Identify - does it mean that Identify message goes through mailboxes of multiple actors (maybe internally without calling "receive" method)?

Actually it is not the Identify but the SelectionPath wrapper that goes through mailboxes, but since Identify is used usually with ActorSelection your observation is correct.

-Endre
 

--
 Victor



On 19.07.2013 14:52, Akka Team wrote:
Hi Ngoc!

I finally had some time, and I figured it out what went wrong. You
actually did manage to deadlock your actor :)

The actor selection you tried to look up looks like the following:

   ActorSelection[Actor[akka://glokka/user/test#244828061]/nonexistent]

A selection consists of two parts, an anchor, which is a known actorref,
and a path part that will be tried to be looked up. The Identify message
travels down from the anchor through the matching children recursively*
until it finds the matching child/children. In this case however the
anchor is blocking on the result of the future, so it cannot process the
Identify, and since it does not process the Identify, it waits until
Timeout. At that point of course the Identify will be processed, but the
result will be delivered to dead letters already.

[* sort-of, I simplified the story a bit]

You can try this by replacing

   context.actorSelection(escape(name))

to

   context.system.actorSelection(escape(name))

which changes the anchor to be the system ref itself, avoiding the deadlock.

Anyway, don't block your actors ;)

-Endre

--
     Read the docs: http://akka.io/docs/
     Check the FAQ: http://akka.io/faq/
     Search the archives: https://groups.google.com/group/akka-user
--- You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+unsubscribe@googlegroups.com.

To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.


vatel

unread,
Jul 24, 2013, 4:08:28 AM7/24/13
to akka...@googlegroups.com
Hi Endre,

> message and will be delivered to the anchor. From the anchor it
> traverses down recursively according to the selection pattern and
> unfolding the wrapped message at a matching actor.

From reading docs & letitcrash blogs I was sure that ActorSelection is
almost the same (at least for very similar purposes) as ActorRef but it
does not point to specific actor identity. Seems we were able to find
RemoteActorRef (with old actorFor) easily, but sending to ActorSelection
requires more complicated lookup of a destination, is it correct?

ActorSelection will (by AkkaTeam intention) take a very important place
in akka world - it will be used in all apps using Remoting without
cluster-aware routers and other high-level cluster logic,
so its behavior should be well-understood by users!

--
Victor

Akka Team

unread,
Jul 24, 2013, 4:43:14 AM7/24/13
to Akka User List
Hi Victor,


From reading docs & letitcrash blogs I was sure that ActorSelection is almost the same (at least for very similar purposes) as ActorRef but it does not point to specific actor identity.

Yes, it is similar.
Seems we were able to find RemoteActorRef (with old actorFor) easily, but sending to ActorSelection requires more complicated lookup of a destination, is it correct?

That is an implementation detail that might change in the future (in fact I hope this particular implementation will change). As for the difference from the old actorFor, don't forget that actor selections support relative paths and wildcards!
 

ActorSelection will (by AkkaTeam intention) take a very important place in akka world - it will be used in all apps using Remoting without cluster-aware routers and other high-level cluster logic,
so its behavior should be well-understood by users!

By that argument each of the internals should be well-understood by users :) We should not expose our internal architectural decisions unless we have very good reason for it -- and of course the source code is always available for those who want to look into the details.

-Endre
 

--
 Victor


--
     Read the docs: http://akka.io/docs/
     Check the FAQ: http://akka.io/faq/
     Search the archives: https://groups.google.com/group/akka-user
--- You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+unsubscribe@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.


vatel

unread,
Jul 24, 2013, 5:02:33 AM7/24/13
to akka...@googlegroups.com
Endre,

> That is an implementation detail that might change in the future (in
> fact I hope this particular implementation will change). As for the
> difference from the old actorFor, don't forget that actor selections
> support relative paths and wildcards!

Thanks! I see now - with wildcards and relative parts it makes sense of
course.

--
Victor

Reply all
Reply to author
Forward
0 new messages