Skip to content

Commit a8a427f

Browse files
benjamingrdanielleadams
authored andcommitted
child_process: support AbortSignal in fork
PR-URL: #36603 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent 578fa0f commit a8a427f

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

doc/api/child_process.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ controller.abort();
351351
<!-- YAML
352352
added: v0.5.0
353353
changes:
354+
- version: REPLACEME
355+
pr-url: https://github.com/nodejs/node/pull/36603
356+
description: AbortSignal support was added.
354357
- version:
355358
- v13.2.0
356359
- v12.16.0
@@ -375,9 +378,11 @@ changes:
375378
* `execPath` {string} Executable used to create the child process.
376379
* `execArgv` {string[]} List of string arguments passed to the executable.
377380
**Default:** `process.execArgv`.
381+
* `gid` {number} Sets the group identity of the process (see setgid(2)).
378382
* `serialization` {string} Specify the kind of serialization used for sending
379383
messages between processes. Possible values are `'json'` and `'advanced'`.
380384
See [Advanced serialization][] for more details. **Default:** `'json'`.
385+
* `signal` {AbortSignal} Allows closing the subprocess using an AbortSignal.
381386
* `silent` {boolean} If `true`, stdin, stdout, and stderr of the child will be
382387
piped to the parent, otherwise they will be inherited from the parent, see
383388
the `'pipe'` and `'inherit'` options for [`child_process.spawn()`][]'s
@@ -386,10 +391,9 @@ changes:
386391
When this option is provided, it overrides `silent`. If the array variant
387392
is used, it must contain exactly one item with value `'ipc'` or an error
388393
will be thrown. For instance `[0, 1, 2, 'ipc']`.
394+
* `uid` {number} Sets the user identity of the process (see setuid(2)).
389395
* `windowsVerbatimArguments` {boolean} No quoting or escaping of arguments is
390396
done on Windows. Ignored on Unix. **Default:** `false`.
391-
* `uid` {number} Sets the user identity of the process (see setuid(2)).
392-
* `gid` {number} Sets the group identity of the process (see setgid(2)).
393397
* Returns: {ChildProcess}
394398

395399
The `child_process.fork()` method is a special case of
@@ -420,6 +424,9 @@ current process.
420424
The `shell` option available in [`child_process.spawn()`][] is not supported by
421425
`child_process.fork()` and will be ignored if set.
422426

427+
The `signal` option works exactly the same way it does in
428+
[`child_process.spawn()`][].
429+
423430
### `child_process.spawn(command[, args][, options])`
424431
<!-- YAML
425432
added: v0.1.90

lib/child_process.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ function fork(modulePath /* , args, options */) {
140140
options.execPath = options.execPath || process.execPath;
141141
options.shell = false;
142142

143-
return spawn(options.execPath, args, options);
143+
return spawnWithSignal(options.execPath, args, options);
144144
}
145145

146146
function _forkChild(fd, serializationMode) {
@@ -758,7 +758,7 @@ function spawnWithSignal(file, args, options) {
758758
validateAbortSignal(options.signal, 'options.signal');
759759
function kill() {
760760
if (child._handle) {
761-
child._handle.kill('SIGTERM');
761+
child.kill('SIGTERM');
762762
child.emit('error', new AbortError());
763763
}
764764
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
setInterval(() => {
2+
// Starting an interval to stay alive.
3+
}, 1000);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
const { mustCall } = require('../common');
4+
const { strictEqual } = require('assert');
5+
const fixtures = require('../common/fixtures');
6+
const { fork } = require('child_process');
7+
8+
{
9+
// Test aborting a forked child_process after calling fork
10+
const ac = new AbortController();
11+
const { signal } = ac;
12+
const cp = fork(fixtures.path('child-process-stay-alive-forever.js'), {
13+
signal
14+
});
15+
cp.on('exit', mustCall());
16+
cp.on('error', mustCall((err) => {
17+
strictEqual(err.name, 'AbortError');
18+
}));
19+
process.nextTick(() => ac.abort());
20+
}
21+
{
22+
// Test passing an already aborted signal to a forked child_process
23+
const ac = new AbortController();
24+
const { signal } = ac;
25+
ac.abort();
26+
const cp = fork(fixtures.path('child-process-stay-alive-forever.js'), {
27+
signal
28+
});
29+
cp.on('exit', mustCall());
30+
cp.on('error', mustCall((err) => {
31+
strictEqual(err.name, 'AbortError');
32+
}));
33+
}

0 commit comments

Comments
 (0)