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

child_process: support numeric signal argument to kill. #9651

Closed
wants to merge 1 commit into from

Conversation

gerrard00
Copy link
Contributor

@gerrard00 gerrard00 commented Nov 17, 2016

Checklist
  • make -j8 test (UNIX), or vcbuild test nosign (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

child_process

Description of change

Modifies the kill function to support numeric signals. I used a type check instead of Number.isInteger because that was the pattern used elsewhere in the code base.

Addresses: #9519

@nodejs-github-bot nodejs-github-bot added the child_process Issues and PRs related to the child_process subsystem. label Nov 17, 2016
@addaleax addaleax added the semver-minor PRs that contain new features and should be released in the next minor version. label Nov 17, 2016
@addaleax
Copy link
Member

Awesome! Do you think you could get a test for this together? There’s a bit on that in https://github.com/nodejs/node/blob/master/doc/guides/writing_tests.md, but I’d assume there are existing tests for the string signal names in test/parallel that you can add to.

And a few tiny commit message things: Could you drop the . at the end of the subject line, try to squeeze the subject line so that it fits into 50 characters (I know it’s hard with child_process… 😄) and add a Fixes: https://github.com/nodejs/node/issues/9519 line?

@gerrard00
Copy link
Contributor Author

Will do!

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch from ae7c0d4 to 29198d4 Compare November 17, 2016 01:43
@addaleax
Copy link
Member

Thanks, apart from the missing tests this looks good!

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch from 29198d4 to 410c589 Compare November 17, 2016 01:55
@gerrard00
Copy link
Contributor Author

There was an existing test for child-process-kill, so I made a copy of that test and modified it to send the numeric value of SIGTERM.

I also modified the commit message as requested. I totally forgot to check that length before pushing.

@@ -356,6 +356,8 @@ ChildProcess.prototype.kill = function(sig) {
signal = 0;
} else if (!sig) {
signal = constants['SIGTERM'];
} else if (typeof sig === 'number') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this replace the if (sig === 0) check a few lines up?

Copy link
Contributor Author

@gerrard00 gerrard00 Nov 17, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that makes more sense. Updated.

@@ -0,0 +1,42 @@
'use strict';
var common = require('../common');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use const instead of var throughout the test.

var gotStdoutEOF = false;
var gotStderrEOF = false;

var cat = spawn(common.isWindows ? 'cmd' : 'cat');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use common.spawnCat()?

var cat = spawn(common.isWindows ? 'cmd' : 'cat');


cat.stdout.on('end', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add common.mustCall() around the callback, then gotStdoutEOF can be completely removed.

});

cat.stderr.on('data', function(chunk) {
assert.ok(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use common.fail() here.

assert.ok(false);
});

cat.stderr.on('end', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add common.mustCall() around the callback, then gotStderrEOF can be completely removed.

gotStderrEOF = true;
});

cat.on('exit', function(code, signal) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use common.mustCall(), and move the assertions for exitCode and termSignal here.

termSignal = signal;
});

assert.equal(cat.killed, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert.strictEqual() please.

assert.equal(cat.killed, false);
// numeric value of SIGTERM
cat.kill(15);
assert.equal(cat.killed, true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert.strictEqual() again here, please.

cat.kill(15);
assert.equal(cat.killed, true);

process.on('exit', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the common.mustCall() changes are made, this can be removed completely.

@gerrard00
Copy link
Contributor Author

@cjihrig Those changes are easy enough, but that will make this test very different than the existing child process kill test. Is that ok?

@cjihrig
Copy link
Contributor

cjihrig commented Nov 17, 2016

The existing test is outdated, even if it's still technically correct. You can also check out the relatively new https://github.com/nodejs/node/blob/master/doc/guides/writing_tests.md.

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch 5 times, most recently from 044fdec to 7c08ce9 Compare November 17, 2016 17:46
@gerrard00
Copy link
Contributor Author

@cjihrig I think I've updated the test correctly. Can you take another look when you have a moment?

Thanks for your patience!

@sam-github
Copy link
Contributor

commit messages should not have a . at the end of them

@gerrard00
Copy link
Contributor Author

@sam-github The period in the commit message was removed based on feedback from @addaleax .

Copy link
Contributor

@sam-github sam-github left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit is missing documentation.

signal = constants['SIGTERM'];
} else if (typeof sig === 'number') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cjihrig should we enforce integral, so 1.2 is not acceptable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sam-github makes sense to me.

if (sig === 0) {
signal = 0;
} else if (!sig) {
if (!sig) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you test this? I'm pretty sure that 0 is now going to become SIGTERM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch! That's totally wrong. I didn't test 0 after making the suggested change. Will fix.

}));

assert.strictEqual(cat.killed, false);
// numeric value of SIGTERM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be constants.os.signals.SIGTERM, so the comment would be unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Copy link
Contributor

@sam-github sam-github left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes child.kill() mysteriously different from process.kill(), doesn't it? They should accept the same arguments.

if (sig === 0) {
signal = 0;
} else if (!sig) {
if (!sig) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition has to be after typeof sig === 'number' otherwise signal 0 will be incorrectly converted to SIGTERM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

@sam-github
Copy link
Contributor

+1 on supporting numeric signals

@sam-github
Copy link
Contributor

I didn't look around, but if there are existing tests for kill, it would be good to add this to them, it can be hard to find tests when there is one big test file that mostly tests a feature the a couple smaller ones sprinkled about that test the incremental additions that were made over time.

^---- I didn't look around, I'm just at the github review tool right now, if its not the case that there is a good test to extend, and this new test file is the best way, pls ignore.

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch 2 times, most recently from 9ba3620 to 798fe20 Compare November 17, 2016 19:24
@gerrard00
Copy link
Contributor Author

@sam-github My lunch break is over, but if I can get the child_process change to an acceptable state modifying process to support the numeric the same way should be easy.

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch from 798fe20 to 5e8cdf9 Compare November 17, 2016 23:55
@gerrard00
Copy link
Contributor Author

@sam-github I took a cut at updating the docs and fixed a typo in that area.

@@ -789,9 +789,10 @@ within the child process to close the IPC channel as well.
added: v0.1.90
-->

* `signal` {String}
* `signal` {String|number} The signal to send, either as a string or number.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String|number -> String|Number

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed! That was actually a c+p from process.md, so I'll add another commit to fix that file. Or should I open a different PR for that?

@cjihrig
Copy link
Contributor

cjihrig commented Nov 18, 2016

if there are existing tests for kill, it would be good to add this to them

The test from this PR could be integrated with test/parallel/test-child-process-kill.js fairly easily.

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch from 5e8cdf9 to 7c45e72 Compare November 18, 2016 06:07
@gerrard00
Copy link
Contributor Author

I'll combine the new test with the existing child process test tomorrow.

@sam-github
Copy link
Contributor

Btw, I still object to adding numeric signal support to child.kill(), and not to process.kill(). Doing so creates an instantaneous bug report: "child.kill accepts numberic signals but process.kill does not". IMO, a missing feature with no bugs is better than a half-feature + a bug report. I request that either you open two PRs simultaneously, put two commits in this PR, or just do both in one commit, so the node API incrementally gets better in a single commit, instead of slightly better and slightly worse.

Also, I'm surprised child_process does its own arg checking at all, instead of calling https://github.com/nodejs/node/blob/master/lib/internal/process.js#L152-L178, so that the arg checks, Error strings, etc. would be provably identical.

I don't have time to look further, but it looks to me like _handle.kill could be replaced with require('internal/process').kill, unifying code and behaviour.

if (sig === 0) {
signal = 0;
if (typeof sig === 'number') {
signal = sig;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should likely check that the value is not an invalid number. For instance:

typeof NaN === 'number'
typeof Infinity === 'number'
typeof 1.1 === 'number'
typeof -1 === 'number'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof sig === 'number' && sig >>> 0 === sig should probably do the trick.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, you just taught me something. I've recently written similar code and used a bunch of || conditions.

Modified as requested.

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch 2 times, most recently from 76e52b8 to 04a8e74 Compare November 21, 2016 17:47
@gerrard00
Copy link
Contributor Author

@cjihrig I combined the tests as request, can you take a look?

@sam-github I'll look into using require('internal/process').kill and modify the code if it works. I'll also open a second PR to modify process and link to it from this PR once I've had a chance to test that.

Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM pending CI

@gerrard00 gerrard00 force-pushed the support_numeric_kill branch from 04a8e74 to fd7a620 Compare November 22, 2016 02:02
@Fishrock123
Copy link
Contributor

@sam-github @targos could you take a look and update your reviews accordingly?

@Fishrock123 Fishrock123 self-assigned this Dec 16, 2016
@@ -1,4 +1,4 @@
# Child Process
#n Child Process
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gerrard00 You have an extra n here. :)

We can fix that on landing though.

@Fishrock123
Copy link
Contributor

The `child.kill()` methods sends a signal to the child process. If no argument
is given, the process will be sent the `'SIGTERM'` signal. See signal(7) for
The `child.kill()` method sends a signal to the child process. If no argument
is given, the process will be sent the `'SIGTERM'` signal. See `signal(7)` for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't put backticks around man page references

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this getting fixed?

}));

assert.equal(cat.killed, false);
cat.kill();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it pass sig here?

}

runTest(constants.os.signals.SIGTERM);
runTest('SIGTERM');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a third test can be added without an argument (to check the default value for signal)

@sam-github
Copy link
Contributor

My comment from #9651 (comment) still stands:

I still object to adding numeric signal support to child.kill(), and not to process.kill(). Doing so creates an instantaneous bug report: "child.kill accepts numeric signals but process.kill does not". IMO, a missing feature with no bugs is better than a half-feature + a bug report.

There is no reason to make these two .kill() APIs inconsistent. Fix them both in one PR.

Landing these kind of changes has historically been a source of node API weirdness, wherein two parts of the API subtlely diverge. There is no reason to do that here, lets just make it all better, consistently, at one time.

@Fishrock123
Copy link
Contributor

@sam-github Ah, yes. I agree on that.

@Trott
Copy link
Member

Trott commented Mar 19, 2017

@gerrard00 Are you still interested in getting this across the finish line?

Adding stalled for now, but if anyone (@gerrard00 or someone else) is actively working on it, please remove that label.

@Trott Trott added the stalled Issues and PRs that are stalled. label Mar 19, 2017
@gerrard00
Copy link
Contributor Author

I'll close this and work on a new PR based on the feedback provided.

@gerrard00 gerrard00 closed this Mar 21, 2017
@thefourtheye
Copy link
Contributor

Actually #10423 covers implicitly this as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem. semver-minor PRs that contain new features and should be released in the next minor version. stalled Issues and PRs that are stalled.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants