Detecting current stack depth

2,638 views
Skip to first unread message

Will Conant

unread,
Jul 15, 2011, 5:58:56 PM7/15/11
to nodejs
Is it possible to detect the current stack depth?

I have a case where a function with an asynchronous interface is far
more likely to complete synchronously than to actually do anything
asynchronous. In an earlier post (linked below) it looks like Ryan
suggests using process.nextTick to make the behavior of such functions
consistent, but that can make things really slow. In fact, from my
testing of the simplest case function that uses process.nextTick vs.
one that just immediately calls its callback, process.nextTick takes
more than 10x as long (which isn't really surprising).

Here is the earlier discussion on the topic:

http://groups.google.com/group/nodejs/browse_thread/thread/6fd56eb6cce4fbf3/a23f953dc1594979?lnk=gst&q=stack+depth#a23f953dc1594979

What I'd really like to do is detect the stack depth and only use
process.nextTick when I'm past a certain threshold. This way, I can
have a really speedy implementation that still won't ever max out the
stack.

Is that possible? Is that horrible?

Thanks in advance!

--
Will Conant

Tom Robinson

unread,
Jul 16, 2011, 8:01:20 PM7/16/11
to nod...@googlegroups.com
Possible? Yes. Efficiently? Not that I know of, but here are the techniques I'm aware of anyway:

1) Probing the stack limit:

function stackLimit() {
var n = 0;
function recurse() { n++; recurse(); }
try { recurse(); } catch (e) {}
return n;
}

2) Counting stack trace length (However by default stack traces are limited to 10 frames. It can be increased by settings Error.stackTraceLimit http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi )

function stackDepth() {
return new Error().stack.split("\n").length - 1;
}

-tom

> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

Bruno Jouhier

unread,
Jul 17, 2011, 7:41:25 AM7/17/11
to nodejs
Detecting the stack depth may be difficult or very inefficient. You
may be able to mitigate the problem by tracking the number of times
your function is reentered and calling process.nextTick once every N
times (N=20 for ex) instead of going through it every time.

Bruno

On Jul 17, 2:01 am, Tom Robinson <tlrobin...@gmail.com> wrote:
> Possible? Yes. Efficiently? Not that I know of, but here are the techniques I'm aware of anyway:
>
> 1) Probing the stack limit:
>
> function stackLimit() {
>     var n = 0;
>     function recurse() { n++; recurse(); }
>     try { recurse(); } catch (e) {}
>     return n;
>
> }
>
> 2) Counting stack trace length (However by default stack traces are limited to 10 frames. It can be increased by settings Error.stackTraceLimithttp://code.google.com/p/v8/wiki/JavaScriptStackTraceApi)
>
> function stackDepth() {
>     return new Error().stack.split("\n").length - 1;
>
> }
>
> -tom
>
> On Jul 15, 2011, at 2:58 PM, Will Conant wrote:
>
>
>
>
>
>
>
> > Is it possible to detect the current stack depth?
>
> > I have a case where a function with an asynchronous interface is far
> > more likely to complete synchronously than to actually do anything
> > asynchronous. In an earlier post (linked below) it looks like Ryan
> > suggests using process.nextTick to make the behavior of such functions
> > consistent, but that can make things really slow. In fact, from my
> > testing of the simplest case function that uses process.nextTick vs.
> > one that just immediately calls its callback, process.nextTick takes
> > more than 10x as long (which isn't really surprising).
>
> > Here is the earlier discussion on the topic:
>
> >http://groups.google.com/group/nodejs/browse_thread/thread/6fd56eb6cc...

Tatumizer

unread,
Jul 17, 2011, 11:50:17 AM7/17/11
to nodejs
Won't it be a good idea for node.js to automatically check current
stack level before invocation of callback, and apply the "nextTick"
trick transparently?
Any ad-hoc solution of application level, on top of being ugly, is not
quite robust: if N is chosen too small, it degrades performance,
it too big - may not work in another version where max stack size is
different, etc...



Scott González

unread,
Jul 17, 2011, 3:53:27 PM7/17/11
to nod...@googlegroups.com
That would be impossible without breaking applications in a seemingly
arbitrary way since it would be converting synchronous calls into
asynchronous calls.

Felix Geisendörfer

unread,
Jul 18, 2011, 8:47:47 AM7/18/11
to nod...@googlegroups.com
You can use my stack trace module for all things stack related:


In your case you could to:

require('stack-trace').get().length

This gets a stack trace directly from v8's stack trace API (which is a PITA, but can be accessed without C++).

Anyway, I don't necessarily recommend this strategy to you. You are probably better of simplifying your API somehow.

--fg
Reply all
Reply to author
Forward
0 new messages