Re: [akka-user] akka-testkit: How to get number of children from *outside* the actor?

1,288 views
Skip to first unread message

Roland Kuhn

unread,
Jan 1, 2013, 7:17:09 AM1/1/13
to akka...@googlegroups.com
Hi Haoyi,

1 jan 2013 kl. 04:17 skrev Haoyi Li:

Inside an actor, I can get the number of children via

context.children.toList.length

However, outside the actor, even when i wrap it in a TestActorRef, this doesn't work:

TAR.underlying.children.toList.length

It always seems to return 0, even when the other one returns 0, 1, 2, etc..

The semantics I'm looking for in my ScalaTest tests is 

eventually(Timeout(Span(5, Seconds))){ assert{ TAR.underlying.children.toList.length == 2} }
eventually(Timeout(Span(5, Seconds))){ assert{ TAR.underlying.children.toList.length == 0} }

Am I reading this right that you expect something to happen between those two lines? In that case you are probably seeing zero all the time because it IS zero, since the TestActorRef sets the CallingThreadDispatcher by default, hence message sends are processed inline where you do the tell() operation.

And even if the actor was running on an asynchronous dispatcher your test would not be reliable because the first line might be executed after the actor has already lost its children again.

a.k.a. "in at most 5  seconds, there will be 2 children. At most 5 seconds after that, all the children will be dead". Is there a nice way of doing this? I could track the creation/termination of children myself, but i'm sure it's already being tracked *somewhere*.

The only place where children are tracked is in their parent’s children list, you were on the right track already.

Another thing to keep in mind: if you cannot observe the children by way of messages they generate, then you cannot observe them within the actor model. Why don’t you test the correct result of the children’s existence? (If they don’t produce any testable result, why create them in the first place?)

Regards,

Roland


Thanks!
-Haoyi

--
>>>>>>>>>> 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 post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user?hl=en.
 
 



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn

Haoyi Li

unread,
Jan 1, 2013, 7:47:45 AM1/1/13
to akka...@googlegroups.com
I'm actually testing their idle timeout. What i'm doing is setting the idleTimeout to, say, 5 seconds, such that if i don't send a message to the actor for 5 seconds it gets a ReceiveTimeout and kills itself with context.stop(self).

I've had my parent actor print out context.children.length when it creates an actor or it receives the Terminated message from the child. I verified that the number of children *is* going up and down (0, 1, 2, 1, 0) while the guy i have polling from the outside using TAR.underlying.children.length reports (0, 0, 0, 0, 0). I'm using ScalaTest's eventually{} block to do this polling.

The outcome that i'm trying to verify is "are the actors properly shutting themselves down when idle, or are they hanging around forever and leaking memory?" which is something i can't directly observe by sending messages (at the moment).

To make the results of this visible I would need to make the child actors respond to some sort of "ping" message, or make the parent actor respond to some sort of "how many children do you have" message, both of which I don't currently do. I guess i'm reluctant to add a bunch of additional message types just for testing purposes. I guess these messages would come in handy later, so maybe i'll just go ahead and implement/use them

-Haoyi

Roland Kuhn

unread,
Jan 1, 2013, 12:03:30 PM1/1/13
to akka...@googlegroups.com
Hi Haoyi,

hmm, trying out the basics gives for me:

scala> startSystem()
[DEBUG] [01/01/2013 17:55:06.659] [run-main] [EventStream(akka://repl)] logger log1-Logging$DefaultLogger started
[DEBUG] [01/01/2013 17:55:06.661] [run-main] [EventStream(akka://repl)] Default Loggers started
don?t forget to system.shutdown()!

scala> TestActorRef(new Actor { context.actorOf(Props.empty); def receive = Actor.emptyBehavior })
res4: akka.testkit.TestActorRef[akka.actor.Actor{def receive: akka.actor.Actor.emptyBehavior.type}] = TestActor[akka://repl/user/$$b]

scala> res4.underlying
res5: akka.actor.ActorCell = akka.testkit.TestActorRef$$anon$1@1f87dad3

scala> res5.children.size
res9: Int = 1

So my conclusion is that the mechanism does indeed work. Without the code I cannot tell you what goes wrong, but I assume that you poll only every second, and the transition (0, 1, 2, 1, 0) might well be faster? If you have a failing test case which you think is an Akka bug, then please file a ticket.

But continuing along the other track, given some actor which provides a service by forwarding to children which are created and destroyed on demand, would it not also make sense to test by sending one query, waiting longer than the timeout, then sending another, and verifying that it was served by a different child? This could be done either by using the “sender” (if they reply directly) or by stubbing out the back-end services which are presumably used by the child actors.

Regards,

Roland

Ricky Clarkson

unread,
Jan 1, 2013, 12:07:39 PM1/1/13
to akka...@googlegroups.com

Fairly unrelated, but that output said don?t forget to... which probably means there's a Unicode ' instead of the ASCII one.  Generally for English it's always '

Roland Kuhn

unread,
Jan 1, 2013, 12:31:15 PM1/1/13
to akka...@googlegroups.com
Hi Ricky,

aeh, no ;-) I’m actually using correct apostrophes (like at the beginning of this sentence) and the REPL and/or SBT manage to mess that up in the initialCommands which produced that output; I’m not sure why that is, since the file encoding of project/AkkaBuild.scala is utf-8 as it should. The ' glyph is the straight ASCII single-quote character which may—in the absence of proper glyphs—be used as the feet mark, just as the so-called straight double-quote may be used as the inch mark (the correct glyphs would be found at the prime and double-prime code points).

http://www.alistapart.com/articles/emen/ <-- this is the reference anyway ;-)

Regards,

Roland

Haoyi Li

unread,
Jan 1, 2013, 8:45:27 PM1/1/13
to akka...@googlegroups.com
I'd rather just see "no more children" to verify that the children have died, since sending messages it leaves open more room for things to go wrong (e.g. actor doesn't respond but actually they're hanging around but in some broken state), whereas "are your children gone?" is less likely to be wrong.

I could have sworn it didn't work, but maybe i just screwed it up. Let me try if I can put together a minimal code snippet to repro.

-Haoyi

Ricky Clarkson

unread,
Jan 2, 2013, 3:35:06 PM1/2/13
to akka...@googlegroups.com

Hi Roland,

Thank you for the links, there's more to it than I realised (isn't there always with typography?).

On English (at least US and UK) keyboards there's no access to the apostrophe that you mention, and it doesn't exist in ASCII.  If you stick to ASCII in program output you minimise the chances of a ? or a rectangle instead of what you want the user to see.  Even if you get it right for Linux, PuTTY (ssh client for Windows) still defaults to the wrong encoding (ISO-8859-1) so someone's going to see something bad.

Ricky.

Roland Kuhn

unread,
Jan 2, 2013, 4:57:42 PM1/2/13
to akka...@googlegroups.com
Hi Ricky,

2 jan 2013 kl. 21:35 skrev Ricky Clarkson:

Hi Roland,

Thank you for the links, there's more to it than I realised (isn't there always with typography?).

On English (at least US and UK) keyboards there's no access to the apostrophe that you mention,


That’s the reason why I use only Apple equipment: <option>-<shift>-] does the trick on the “Int’l English” keyboard. And the iPhone is (at least it was at the time I checked) the only mobile device I could find which supports all those nice glyphs on its virtual keyboard.

and it doesn't exist in ASCII.  If you stick to ASCII in program output you minimise the chances of a ? or a rectangle instead of what you want the user to see.  Even if you get it right for Linux, PuTTY (ssh client for Windows) still defaults to the wrong encoding (ISO-8859-1) so someone's going to see something bad.


Yes, that is true. However, I like to think that we left the stone-age of computing behind—and consequently disregard that some people might still live in those caves ;-)

Regards,

Roland
Reply all
Reply to author
Forward
0 new messages