-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
doc: exit event is not guaranteed to fire #2861
Conversation
@@ -59,6 +59,9 @@ finished running the process will exit. Therefore you **must** only perform | |||
checks on the module's state (like for unit tests). The callback takes one | |||
argument, the code the process is exiting with. | |||
|
|||
This event is not guaranteed to fire in all situations. For example, if the | |||
process receives `SIGINT`, it may exit without firing this event. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Trott, please review line 247 below. It's the last bullet point under the section on Signal Events
I might say something like:
The exit event will not fire if the process receives one of three program interrupts intended to override the runtime regardless of call stack depth, i.e.
SIGINT
,SIGTERM
, orSIGKILL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the last bullet point might be specific to this: Note that Windows does not support sending Signals, but Node.js offers some emulation with process.kill(), and child_process.kill():
So I wasn't sure that it applied in all cases, or if it was specific to signals received via process.kill()
and child_process.kill()
. On reflection, that doesn't really make any sense. I wonder if that sentence is actually supposed to have a period at the end rather than a colon.
So yeah, I'll try to edit it a bit more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would seem that the list of interrupts that bypass the exit
event is not limited to just those three. SIGHUP
seems to do it too, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. that's still just another user shutdown like ctrl
+ c
stuff. here's a list:
http://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well no nevermind, it's a much different signal from ctrl
+ c
stuff.
SIGHUP
is any hangup, so while it could happen in the terminal, i think it could also occur from any socket opened by http
or net
or a binding, etc
789276d
to
f4e001c
Compare
- Sending `SIGINT`, `SIGTERM`, and `SIGKILL` cause the unconditional exit of the | ||
target process. | ||
|
||
Note that Windows does not support sending Signals, but Node.js offers some | ||
emulation with `process.kill()`, and `child_process.kill()`. Sending signal `0` | ||
can be used to search for the existence of a process |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/search/check/?
EDIT: Or 'test', like below.
If you use 'refine' as the short description, you should have a long description that explains what. :-) LGTM apart from that and a suggestion. |
b65d753
to
a1165b4
Compare
This change: * notes that the exit event is not guaranteed to fire * provides an example situation where the exit event may not fire * makes a minor copyediting change * enforces 80 character wrap in one place where it was not honored Fixes: nodejs#2853
a1165b4
to
2334be6
Compare
@@ -218,7 +221,7 @@ Note: | |||
the terminal mode before exiting with code `128 + signal number`. If one of | |||
these signals has a listener installed, its default behavior will be removed | |||
(Node.js will no longer exit). | |||
- `SIGPIPE` is ignored by default, it can have a listener installed. | |||
- `SIGPIPE` is ignored by default. It can have a listener installed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to this PR, but is this a recent thing? I remember having to use https://www.npmjs.com/package/epipebomb in the past to prevent rare, but real issues from occurring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
git blame
says that line was introduced in the docs in October 2013 with 155df9ca7. The behavior predates the documentation of it, but I don't know by how much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm if that means that epipebomb is therefore useless?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using current node (4.0.0), I'm able to trigger EPIPE
on OS X with:
node -e 'for (var i = 0; i < 100; i++) console.log(i)' | head
If I install epipebomb and require it first, it doesn't fix anything.
So, I guess it's useless now? But you can still get EPIPE
errors? Not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't that mean that the documentation saying "SIGPIPE
is ignored by default" is wrong? I think it would be nice if that would just be solved in Node once and for all (not in docs).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it's still needed :(
Is there any reason why that is not default behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's wrong. Writing to a pipe that can't read results in both SIGPIPE
signal and EPIPE
error. The signal is ignored while the error is not. At least, that's how I'm seeing it. Correction welcome. And I suspect the docs can be clarified on that. (Feel free to PR something better if you have a good idea.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signal is ignored while the error is not
@Trott wait a minute, what do you mean by ignoring the signal?
also what do you think about my idea from just a few minutes ago in the issue discussion? #2853 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably going to stop after this comment because there are people who are waaaaay more informed than I am about how this works in Node and why. If I keep going without doing some homework, I'll probably only create annoyance and/or confusion.
@reqshark I used the word "ignore" because that's what's in the docs. I meant nothing precise by it.
@ronkorving I agree that it's surprising that the epipebomb-enabled behavior isn't the default as that seems to be the default everywhere else (judging from the fact that I've never run up against it piping output through head
from Perl, Python, Ruby, what have you).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yo @Trott just add this bookmark, https://www.gnu.org/software/libc/manual/html_mono/libc.html
SIGPIPE
is a signal from the kernel. EPIPE
is an error code. In the linked issue discussion I was talking more about termination signals (not EPIPE
nor its conjoined twin, SIGPIPE
)
Going to go and merge this on the grounds that there is a |
This change: * notes that the exit event is not guaranteed to fire * provides an example situation where the exit event may not fire * makes a minor copyediting change * enforces 80 character wrap in one place where it was not honored Fixes: #2853 PR-URL: #2861 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Landed in 43cb1dd |
@Trott I don't think merging something in over objections with the claim that its an improvement is really the way to go. Particularly when both meaningful changes it introduces have been contested as inaccurate. Even if this was a vote, you have one +, one -, and that's not an overwhelming endorsement. I wrote the docs you are changing, I have some familiarity with them! Of course, Ben probably wrote the code, but he knows that SIGINT does not unconditionally cause exit of a target process on Unix, I think he didn't notice that you'd decontexualized that statement. @bnoordhuis, comment? Saying that an event "may be fired" is not particularly useful. Under what conditions will it be emitted or not emitted? I would ask that you revert this, reopen it, and continue the discussion. /cc @rvagg We were discussing premature closing of PRs a few hours ago... I am thinking there needs to be more clarity on how fast things are closed. |
@sam-github I apologize about that. I didn't see your comments. (They got lost in the inline comments. That's not an excuse, just an explanation. I should have been more meticulous.) Had I seen your comments, I would not have merged. I've opened #2918 to try to remediate, but if you'd prefer a full-on revert of these changes, I'm happy to do that (or let someone else do it). |
OK, I see, things get lost in github sometimes, that makes more sense. I think just making the statement about when the exit event happens more definite and making sure the always terminate statement is recontextualized is enough. How you do that is up to you, don't revert unless that makes it easy for you. |
One exit handler would be more consistent with the idea of an exit event handler. @sam-github, docs wont solve that. |
@reqshark I'm missing some context, what do you mean by one exit handler? There is only one exit event. And what "that" are you refering to? |
no there are plenty of other exit-like events. these other process exits or termination events bypass the exit event handler; they go by other names. process.on('exit', function() {
console.log('this never happens');
})
process.on('SIGHUP', function () {
console.log('however this prevents exit')
}); I recently moved from New York City to the Peninsula, about 20 minutes south of San Francisco. While the area is nice, I often see streets that go by more than one name. Arbitrarily the city planners around here will give more than one name to a street and change the name at a crossing or at a certain stoplight. That's basically what |
also @sam-github, that was unclear, sorry i never meant "exit handler", i just mean "exit event" |
This change: * notes that the exit event is not guaranteed to fire * provides an example situation where the exit event may not fire * makes a minor copyediting change * enforces 80 character wrap in one place where it was not honored Fixes: nodejs#2853 PR-URL: nodejs#2861 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This change:
Fixes: #2853