Skip to content

Commit 385e8e8

Browse files
benjamingrtargos
authored andcommitted
child_process: support AbortSignal in fork
PR-URL: #36603 Backport-PR-URL: #38386 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 0b691ce commit 385e8e8

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-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
@@ -127,7 +127,7 @@ function fork(modulePath /* , args, options */) {
127127
options.execPath = options.execPath || process.execPath;
128128
options.shell = false;
129129

130-
return spawn(options.execPath, args, options);
130+
return spawnWithSignal(options.execPath, args, options);
131131
}
132132

133133
function _forkChild(fd, serializationMode) {
@@ -719,7 +719,7 @@ function spawnWithSignal(file, args, options) {
719719
validateAbortSignal(options.signal, 'options.signal');
720720
function kill() {
721721
if (child._handle) {
722-
child._handle.kill('SIGTERM');
722+
child.kill('SIGTERM');
723723
child.emit('error', new AbortError());
724724
}
725725
}
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,34 @@
1+
// Flags: --experimental-abortcontroller
2+
'use strict';
3+
4+
const { mustCall } = require('../common');
5+
const { strictEqual } = require('assert');
6+
const fixtures = require('../common/fixtures');
7+
const { fork } = require('child_process');
8+
9+
{
10+
// Test aborting a forked child_process after calling fork
11+
const ac = new AbortController();
12+
const { signal } = ac;
13+
const cp = fork(fixtures.path('child-process-stay-alive-forever.js'), {
14+
signal
15+
});
16+
cp.on('exit', mustCall());
17+
cp.on('error', mustCall((err) => {
18+
strictEqual(err.name, 'AbortError');
19+
}));
20+
process.nextTick(() => ac.abort());
21+
}
22+
{
23+
// Test passing an already aborted signal to a forked child_process
24+
const ac = new AbortController();
25+
const { signal } = ac;
26+
ac.abort();
27+
const cp = fork(fixtures.path('child-process-stay-alive-forever.js'), {
28+
signal
29+
});
30+
cp.on('exit', mustCall());
31+
cp.on('error', mustCall((err) => {
32+
strictEqual(err.name, 'AbortError');
33+
}));
34+
}

0 commit comments

Comments
 (0)