-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
process: Send signal name to signal handlers #15606
Conversation
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 swap the callback arguments? Their current order makes this PR a needlessly backwards incompatible change.
That said, I'm -0 on this PR. It's mostly redundant and signal numbers are different across platforms. I don't see the point, TBH.
@bnoordhuis Thanks for the feedback - I have swapped the arguments as requested. One additional reason why this could be beneficial is that currently if you want to know the signal's code you have to look it up in the |
@robertrossmann thanks for taking the time to put together this PR. We have something similar in most of our services, so I can definitely appreciate the value in this. I'd be happy to help out to try and get the test working (at least on macOS and linux) as well |
Thanks @evanlucas for offering to help me with the tests. To describe current situation: The test attaches a signal listener wrapped in I wrote most of the test code by following test-signal-handler.js test. I am unsure if the new test file needs anything extra. |
test/parallel/test-signal-args.js
Outdated
'use strict'; | ||
|
||
const assert = require('assert'); | ||
const common = require('../common'); |
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.
Please move this up a line so that it is the first require()
.
test/parallel/test-signal-args.js
Outdated
const common = require('../common'); | ||
const os = require('os'); | ||
|
||
console.log(`process.pid: ${process.pid}`); |
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.
Please drop the console.log()
.
test/parallel/test-signal-args.js
Outdated
process.once('SIGINT', common.mustCall((signal, code) => { | ||
assert.strictEqual(code, os.constants.signals[signal]); | ||
assert.strictEqual(signal, 'SIGINT'); | ||
}), 1); |
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.
You can drop the 1
here and below, as that is the default value.
doc/api/process.md
Outdated
process.on('SIGINT', handle); | ||
process.on('SIGTERM', handle); | ||
|
||
function handle(signal, code) { |
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 think the documentation needs to mention that these new arguments are provided.
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 am sorry but why is the signal added as well? The handler itself already listens to the signal and that is redundant therefore?
@cjihrig Thank you for your feedback - I have updated the code as requested and added extra sentence to the docs about the function arguments. |
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.
Code LGTM, but like @bnoordhuis I question whether or not we really need it.
doc/api/process.md
Outdated
@@ -350,6 +350,9 @@ Signal events will be emitted when the Node.js process receives a signal. Please | |||
refer to signal(7) for a listing of standard POSIX signal names such as | |||
`SIGINT`, `SIGHUP`, etc. | |||
|
|||
The signal handler will receive two arguments: the signal's name (`'SIGINT'`, | |||
`'SIGTERM'` etc.) and the signal's numeric code, (`2`, `15`, respectively). |
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.
Missing a comma after SIGTERM
.
numeric code, (2
, 15
, respectively) -> numeric code, respectively.
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.
Fixed, thanks. I preserved the numeric examples, though - let me know if you intended to have them removed.
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 did mean to remove them. I don't think they add much value. If you're going to keep them, please throw an , etc.
in there too.
Sorry for being pedantic but, can't this just be put in a module that maps separate handlers with their appropriate info and then does the dispatch? If that already exists, does it not work well? |
@Fishrock123 You are correct that the functionality included in this PR can easily be achieved by other means (see my initial example). It is very easy to wrap a signal handler in an arrow function and pass the signal name to the actual handler, and it is equally easy to look up that signal's code from This PR is just an attempt to improve the ergonomics of such task by not requiring the developer to do these extra steps when Node.js already can provide all the information necessary. So, yes - Node.js does not need this - it does not introduce any new features or functionality. It just attempts to improve the way people work with signal handlers. |
I am -0 on this if this should land I would prefer to land it without the redundancy of the signal. |
@BridgeAR The signal is given to the handler so that the handler knows which signal triggered it. This is useful in situations where the same handler is listening on multiple signals and you want to know which signal caused the handler to be triggered. As I mentioned earlier, the whole point of this PR is merely ergonomics - I can still achieve my goal using other means (arrow functions, looking up the signal code elsewhere etc.). |
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.
My apologies, I asked you to swap the callback arguments because I thought listeners already received the signal name as their first argument, but they don't.
I'm still not convinced that the signal number (the second argument) is all that useful.
It's redundant and might turn into steady source of bugs if programmers assume that because SIGFOO is 42 on platforms A and B, it's also 42 on C and D, and then find out the hard way when it's not.
doc/api/process.md
Outdated
@@ -350,6 +350,9 @@ Signal events will be emitted when the Node.js process receives a signal. Please | |||
refer to signal(7) for a listing of standard POSIX signal names such as | |||
`SIGINT`, `SIGHUP`, etc. | |||
|
|||
The signal handler will receive two arguments: the signal's name (`'SIGINT'`, | |||
`'SIGTERM'`, etc.) and the signal's numeric code. |
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.
Maybe move this below the next paragraph or merge them. I think an unwitting reader would assume the second one is a continuation of the first, i.e., that it's about the callback's arguments.
I think I'm ok with this, but I do also prefer @bnoordhuis's recommendation to not pass the signal number. If the signal number is necessary, it can be retrieved from |
I have rebased on current master and hopefully addressed all review feedback. I have also fixed the tests 🎉: |
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 seems the test suite got stuck somewhere. 🤔 Can someone look at it and perhaps restart it? Thank you! PS. Should I rebase once again or is it okay if this is based off of some older commit? |
Ooops, looks like I forgot to run I have fixed all linter errors, rebased again from master and made sure the test suite still passes locally. Apologies for the hurdle! |
Looks like the CI did not properly report back to this PR - I randomly checked some of the tasks and they are listed as successful on CI. Just FYI. |
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.
Nothing blocking imo but a small fix
test/parallel/test-signal-args.js
Outdated
|
||
// Prevent Node.js from exiting due to empty event loop before signal handlers | ||
// are fired | ||
setTimeout(() => {}, 0); |
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.
setImmediate
would be better. Note also that 0
coerces to 1
in timers durations.
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.
Then again, the test is failing on Windows. https://ci.nodejs.org/job/node-test-binary-windows/11940/
The CI isn't outputting a stack for some reason:
Maybe someone from @nodejs/platform-windows can run the test on a local machine? |
@Fishrock123 Thanks for the suggestion, I updated the code. About windows failure, from the docs:
Could it be that the windows process is being unconditionally terminated due to it receiving There is a mention of some signal emulation on Windows but I have no experience with win32 systems. Just a wild guess here. |
Is there anything I can do to have this merged? There is only one pending review from @Fishrock123 which has been addressed (win32 failures). Thank you! |
Windows issues appear to be fixed.
This is looking good, just waiting for the last few CI bots to finish |
PR-URL: #15606 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
Landed in 9b2cf1c |
PR-URL: #15606 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
PR-URL: #15606 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
Notable changes: * async\_hooks: - add trace events to async_hooks (Andreas Madsen) #15538 - add provider types for net server (Andreas Madsen) #17157 * console: - console.debug can now be used outside of the inspector (Benjamin Zaslavsky) #17033 * deps: - upgrade libuv to 1.18.0 (cjihrig) #17282 - patch V8 to 6.2.414.46 (Myles Borins) #17206 * module: - module.builtinModules will return a list of built in modules (Jon Moss) #16386 * n-api: - add helper for addons to get the event loop (Anna Henningsen) #17109 * process: - process.setUncaughtExceptionCaptureCallback can now be used to customize behavior for `--abort-on-uncaught-exception` (Anna Henningsen) #17159 - A signal handler is now able to receive the signal code that triggered the handler. (Robert Rossmann) #15606 * src: - embedders can now use Node::CreatePlatform to create an instance of NodePlatform (Cheng Zhao) #16981 * stream: - writable.writableHighWaterMark and readable.readableHighWaterMark will return the values the stream object was instantiated with (Calvin Metcalf) #12860 * **Added new collaborators** * [maclover7](https://github.com/maclover7) Jon Moss * [guybedford](https://github.com/guybedford) Guy Bedford * [hashseed](https://github.com/hashseed) Yang Guo PR-URL: Coming Soon
Notable changes: * async\_hooks: - add trace events to async_hooks (Andreas Madsen) #15538 - add provider types for net server (Andreas Madsen) #17157 * console: - console.debug can now be used outside of the inspector (Benjamin Zaslavsky) #17033 * deps: - upgrade libuv to 1.18.0 (cjihrig) #17282 - patch V8 to 6.2.414.46 (Myles Borins) #17206 * module: - module.builtinModules will return a list of built in modules (Jon Moss) #16386 * n-api: - add helper for addons to get the event loop (Anna Henningsen) #17109 * process: - process.setUncaughtExceptionCaptureCallback can now be used to customize behavior for `--abort-on-uncaught-exception` (Anna Henningsen) #17159 - A signal handler is now able to receive the signal code that triggered the handler. (Robert Rossmann) #15606 * src: - embedders can now use Node::CreatePlatform to create an instance of NodePlatform (Cheng Zhao) #16981 * stream: - writable.writableHighWaterMark and readable.readableHighWaterMark will return the values the stream object was instantiated with (Calvin Metcalf) #12860 * **Added new collaborators** * [maclover7](https://github.com/maclover7) Jon Moss * [guybedford](https://github.com/guybedford) Guy Bedford * [hashseed](https://github.com/hashseed) Yang Guo PR-URL: #17631
Notable changes: * async\_hooks: - add trace events to async_hooks (Andreas Madsen) #15538 - add provider types for net server (Andreas Madsen) #17157 * console: - console.debug can now be used outside of the inspector (Benjamin Zaslavsky) #17033 * deps: - upgrade libuv to 1.18.0 (cjihrig) #17282 - patch V8 to 6.2.414.46 (Myles Borins) #17206 * module: - module.builtinModules will return a list of built in modules (Jon Moss) #16386 * n-api: - add helper for addons to get the event loop (Anna Henningsen) #17109 * process: - process.setUncaughtExceptionCaptureCallback can now be used to customize behavior for `--abort-on-uncaught-exception` (Anna Henningsen) #17159 - A signal handler is now able to receive the signal code that triggered the handler. (Robert Rossmann) #15606 * src: - embedders can now use Node::CreatePlatform to create an instance of NodePlatform (Cheng Zhao) #16981 * stream: - writable.writableHighWaterMark and readable.readableHighWaterMark will return the values the stream object was instantiated with (Calvin Metcalf) #12860 * **Added new collaborators** * [maclover7](https://github.com/maclover7) Jon Moss * [guybedford](https://github.com/guybedford) Guy Bedford * [hashseed](https://github.com/hashseed) Yang Guo PR-URL: #17631
* SignalsListener signal name nodejs/node#15606 * created Node 8 folder * Create tsconfig.json * Create tslint.json * Create node-tests.ts * Node 9 * update node header * Tabs to spaces * copy inspector.d.ts to v8 folder * correct path mapping for v8 * disable no-declare-current-package for v8 module * Correct version to 9.3.x Add writableHighWaterMark/readableHighWaterMark to WriteStream/ReadStream fixed setUncaughtExceptionCaptureCallback() Add module.builtinModules change os.EOL to const add writableHighWaterMark to Duplex writableHighWaterMark and readableHighWaterMark are readonly * fs.realpathSync.native and fs.realpath.native * fs.realpath.native tests
* SignalsListener signal name nodejs/node#15606 * created Node 8 folder * Create tsconfig.json * Create tslint.json * Create node-tests.ts * Node 9 * update node header * Tabs to spaces * copy inspector.d.ts to v8 folder * correct path mapping for v8 * disable no-declare-current-package for v8 module * Correct version to 9.3.x Add writableHighWaterMark/readableHighWaterMark to WriteStream/ReadStream fixed setUncaughtExceptionCaptureCallback() Add module.builtinModules change os.EOL to const add writableHighWaterMark to Duplex writableHighWaterMark and readableHighWaterMark are readonly * fs.realpathSync.native and fs.realpath.native * fs.realpath.native tests
Is this something we would want to backport to 8.x? |
PR-URL: nodejs#15606 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
Backport-PR-URL: #22380 PR-URL: #15606 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
process
Description
Allow the signal handler to receive the signal code that triggered the handler.
This is useful in situations where you have one common signal handler to gracefully exit a Node.js process (ie. one handler for
SIGINT
andSIGTERM
) and you still want to know exactly which signal was used to stop the process.Before
After