Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecating the process._startProfilerIdleNotifier & process._stopProfilerIdleNotifier methods #19009

Closed
JacksonTian opened this issue Feb 26, 2018 · 13 comments

Comments

@JacksonTian
Copy link
Contributor

JacksonTian commented Feb 26, 2018

When I browse the source code of src/node.cc, I found _startProfilerIdleNotifier & _stopProfilerIdleNotifier methods. These methods never be documented and haven't any test cases in test/*.

I am proposing that we can mark the two methods as deprecated and remove later.

In user land, v8-profiler can do things better.

If no against for this proposal, I will start the work.

CC @nodejs/collaborators

@JacksonTian JacksonTian changed the title remove remove the process._startProfilerIdleNotifier & process._stopProfilerIdleNotifier methods Feb 26, 2018
@JacksonTian JacksonTian changed the title remove the process._startProfilerIdleNotifier & process._stopProfilerIdleNotifier methods Deprecate the process._startProfilerIdleNotifier & process._stopProfilerIdleNotifier methods Feb 26, 2018
@JacksonTian JacksonTian changed the title Deprecate the process._startProfilerIdleNotifier & process._stopProfilerIdleNotifier methods Deprecating the process._startProfilerIdleNotifier & process._stopProfilerIdleNotifier methods Feb 26, 2018
@bnoordhuis
Copy link
Member

I know I added them but I'll be damned if I remember why. I'm good with removing them.

@mcollina
Copy link
Member

👍 to remove or runtime-deprecate them.

@benjamingr
Copy link
Member

benjamingr commented Feb 27, 2018

Anyone using these methods in userland?

@ofrobots
Copy link
Contributor

ofrobots commented Jul 6, 2018

Just found this issue while trying to understand why Node doesn't notify the VM for idle phases by default.

I don't know the motivation that @bnoordhuis had originally. My motivation is from a profiler perspective. A profiler (e.g. Chrome DevTools) should be able to distinguish JS execution vs. native execute vs. idle time. Currently, when no JS is executing, the profiler has no idea if Node was spending time in C++ or was really idle.

Apart from the the diagnostic use-case, I think the VM might also be able to get a better idea of process load based on how busy the host (Node) seems to be, and might be able to take advantage of this in tweaking GC and background compilation heuristics. This is not profiling specific.

IOW, I think we should

  1. Perform idle notifications by default. I think the current mechanism (uv_prepare_t, uv_check_t) might do a few too many notifications (once per loop iteration). I think this can be improved.
  2. If we do that, we do not need to expose these functions to JavaScript. I'm +1 on deprecating and removing these, if we do the previous bullet (I'd be happy to go implement that).

WDYT? Any concerns/objections?

@joyeecheung
Copy link
Member

@ofrobots (This may not be helpful but FWIW) I think I've seen somewhere in the comments that the idle notifications in core were removed because they "did not work well". But those notes were ancient and it's probably not a bad time to revisit this and integrate the core better with the VM.

@ofrobots
Copy link
Contributor

ofrobots commented Jul 9, 2018

@joyeecheung thanks! if you have pointers to some of these discussions, those would be very useful for me. Perhaps you were thinking of requestIdleCallback (#2543) – which is something very different?

@joyeecheung
Copy link
Member

@ofrobots Did some archeology and I am pretty sure I was talking about d607d85 although it seems specific to regulating GC

@Yogu
Copy link

Yogu commented Nov 16, 2018

@ofrobots I don't know any node internals, but I'm 100% with you on enabling these by default (if there are no significant performance problems). And thanks a lot for this PR where you fixed it in a project - I shamelessly copied it into my project to get idle times working. ❤️

@Trott
Copy link
Member

Trott commented Apr 22, 2020

Looks like these are now in src/node_process_methods.cc.

What's the status of this?

  1. Perform idle notifications by default. I think the current mechanism (uv_prepare_t, uv_check_t) might do a few too many notifications (once per loop iteration). I think this can be improved.
  2. If we do that, we do not need to expose these functions to JavaScript. I'm +1 on deprecating and removing these, if we do the previous bullet (I'd be happy to go implement that).

Did the first bullet point ever happen? If not, is there someone motivated to implement it? I don't get the impression that either @JacksonTian or @ofrobots are terribly active on the project these days, but I'd be thrilled to see them or anyone else jump in on this to get it across the finish line.

@bnoordhuis
Copy link
Member

I remember what my motivation for adding those methods was. It's to stop the V8 profiler from counting time spent sleeping in epoll_wait(2) or kevent(2) as CPU (i.e., running) time.

We handle that in libuv now so in that respect the start/stop methods aren't necessary anymore:

uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);

There's probably still value in post-processing tools knowing when node is sleeping but prepare/check handles are too coarse for that: I/O callbacks run in between and, as a result, are counted as idle time.

@Trott
Copy link
Member

Trott commented Apr 26, 2020

I remember what my motivation for adding those methods was. It's to stop the V8 profiler from counting time spent sleeping in epoll_wait(2) or kevent(2) as CPU (i.e., running) time.

We handle that in libuv now so in that respect the start/stop methods aren't necessary anymore:

uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);

There's probably still value in post-processing tools knowing when node is sleeping but prepare/check handles are too coarse for that: I/O callbacks run in between and, as a result, are counted as idle time.

I'm sorry, but I'm not sure I fully understand. Does this mean that this issue can be closed? Or does it mean that it can be closed after we do some work in core to rely on libuv's handling of this?

@bnoordhuis
Copy link
Member

There's a bit of scope creep going on in this issue. Let's start with @JacksonTian's proposal to deprecate the methods.

I think that's a fine thing to do - they're not necessary and I shouldn't have added them. 6820054...f649626 is the relevant changeset; I added them because I could, not because I should.

This issue should stay open until that change is made.

Next is @ofrobots's sugggestion: perform idle notifications by default. I also think that's a fine thing to do but it's a separate issue. Let's open a new issue for that.

addaleax added a commit to addaleax/node that referenced this issue Apr 29, 2020
This removes the functionality behind
`process._startProfilerIdleNotifier()` and
`process._stopProfilerIdleNotifier()` and instead always informs V8
over the current event loop state.

The methods themselves are left as noop stubs as per our deprecation
policy.

Fixes: nodejs#19009
@addaleax
Copy link
Member

If we decide to perform idle notifications by default, then I would just indefinitely leave these methods as no-op stubs, which renders deprecating unnecessary. I’ve opened #33138 to implement that.

bnoordhuis added a commit to bnoordhuis/io.js that referenced this issue Jun 22, 2020
I added it in commit 57231d5 ("src: notify V8 profiler when we're
idle") from October 2013 as a stop-gap measure to measure CPU time
rather than wall clock time, otherwise processes that spend a lot
of time sleeping in system calls give a false impression of being
very busy.

That fix is not without drawbacks because the idle flag is set before
libuv makes I/O callbacks and cleared again after. I/O callbacks can
result into calls into JS code and executing JS code is as non-idle
as you can get.

In commit 96ffcb9 ("src: reduce cpu profiler overhead") from January
2015, I made Node.js block off the SIGPROF signal that V8's CPU profiler
uses before Node.js goes to sleep. The goal of that commit is to reduce
the overhead from EINTR system call wakeups but it also has the pleasant
side effect of fixing what the idle notifier tried to fix.

This commit removes the idle notifier and turns the JS process object
methods into no-ops.

Fixes: nodejs#19009
Refs: nodejs#33138
codebytere pushed a commit that referenced this issue Jun 27, 2020
I added it in commit 57231d5 ("src: notify V8 profiler when we're
idle") from October 2013 as a stop-gap measure to measure CPU time
rather than wall clock time, otherwise processes that spend a lot
of time sleeping in system calls give a false impression of being
very busy.

That fix is not without drawbacks because the idle flag is set before
libuv makes I/O callbacks and cleared again after. I/O callbacks can
result into calls into JS code and executing JS code is as non-idle
as you can get.

In commit 96ffcb9 ("src: reduce cpu profiler overhead") from January
2015, I made Node.js block off the SIGPROF signal that V8's CPU profiler
uses before Node.js goes to sleep. The goal of that commit is to reduce
the overhead from EINTR system call wakeups but it also has the pleasant
side effect of fixing what the idle notifier tried to fix.

This commit removes the idle notifier and turns the JS process object
methods into no-ops.

Fixes: #19009
Refs: #33138

PR-URL: #34010
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
codebytere pushed a commit that referenced this issue Jun 30, 2020
I added it in commit 57231d5 ("src: notify V8 profiler when we're
idle") from October 2013 as a stop-gap measure to measure CPU time
rather than wall clock time, otherwise processes that spend a lot
of time sleeping in system calls give a false impression of being
very busy.

That fix is not without drawbacks because the idle flag is set before
libuv makes I/O callbacks and cleared again after. I/O callbacks can
result into calls into JS code and executing JS code is as non-idle
as you can get.

In commit 96ffcb9 ("src: reduce cpu profiler overhead") from January
2015, I made Node.js block off the SIGPROF signal that V8's CPU profiler
uses before Node.js goes to sleep. The goal of that commit is to reduce
the overhead from EINTR system call wakeups but it also has the pleasant
side effect of fixing what the idle notifier tried to fix.

This commit removes the idle notifier and turns the JS process object
methods into no-ops.

Fixes: #19009
Refs: #33138

PR-URL: #34010
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
10 participants