Skip to content

Commit 75c1f6b

Browse files
authored
doc: discourage AbortSignal cleanup for long-lived resources
Signed-off-by: Efe Karasakal <hi@efe.dev> PR-URL: #64342 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent f96dccc commit 75c1f6b

4 files changed

Lines changed: 108 additions & 0 deletions

File tree

‎doc/api/child_process.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ can be used to specify the character encoding used to decode the stdout and
242242
stderr output. If `encoding` is `'buffer'`, or an unrecognized character
243243
encoding, `Buffer` objects will be passed to the callback instead.
244244

245+
> Using the `signal` option to destroy a long-lived child process as a resource
246+
> cleanup mechanism is deprecated. The `signal` option remains appropriate for
247+
> cancellation, externally propagated aborts, and timeouts. See
248+
> [DEP0209](deprecations.md#dep0209-using-abortsignal-to-dispose-of-resources).
249+
245250
```cjs
246251
const { exec } = require('node:child_process');
247252
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
@@ -390,6 +395,11 @@ except that it does not spawn a shell by default. Rather, the specified
390395
executable `file` is spawned directly as a new process making it slightly more
391396
efficient than [`child_process.exec()`][].
392397

398+
> Using the `signal` option to destroy a long-lived child process as a resource
399+
> cleanup mechanism is deprecated. The `signal` option remains appropriate for
400+
> cancellation, externally propagated aborts, and timeouts. See
401+
> [DEP0209](deprecations.md#dep0209-using-abortsignal-to-dispose-of-resources).
402+
393403
The same options as [`child_process.exec()`][] are supported. Since a shell is
394404
not spawned, behaviors such as I/O redirection and file globbing are not
395405
supported.
@@ -585,6 +595,11 @@ current process.
585595
The `shell` option available in [`child_process.spawn()`][] is not supported by
586596
`child_process.fork()` and will be ignored if set.
587597

598+
> Using the `signal` option to destroy a long-lived child process as a resource
599+
> cleanup mechanism is deprecated. The `signal` option remains appropriate for
600+
> cancellation, externally propagated aborts, and timeouts. See
601+
> [DEP0209](deprecations.md#dep0209-using-abortsignal-to-dispose-of-resources).
602+
588603
If the `signal` option is enabled, calling `.abort()` on the corresponding
589604
`AbortController` is similar to calling `.kill()` on the child process except
590605
the error passed to the callback will be an `AbortError`:
@@ -735,6 +750,11 @@ process, the default is [`process.env`][].
735750
736751
`undefined` values in `env` will be ignored.
737752
753+
> Using the `signal` option to destroy a long-lived child process as a resource
754+
> cleanup mechanism is deprecated. The `signal` option remains appropriate for
755+
> cancellation, externally propagated aborts, and timeouts. See
756+
> [DEP0209](deprecations.md#dep0209-using-abortsignal-to-dispose-of-resources).
757+
738758
Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the
739759
exit code:
740760

‎doc/api/deprecations.md‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4718,6 +4718,85 @@ replacing it keeps being called by [`server.listen()`][], and it will be
47184718
removed in a future version of Node.js. Use [`server.listen()`][] instead of
47194719
calling or overriding `_listen2`.
47204720
4721+
### DEP0209: Using `AbortSignal` to dispose of resources
4722+
4723+
<!-- YAML
4724+
changes:
4725+
- version: REPLACEME
4726+
pr-url: https://github.com/nodejs/node/pull/64342
4727+
description: Documentation-only deprecation.
4728+
-->
4729+
4730+
Type: Documentation-only
4731+
4732+
Using `AbortSignal` to destroy long-lived resources is deprecated. Prefer
4733+
`using` for resource cleanup.
4734+
4735+
`AbortSignal` is still a good fit for canceling actions, propagating
4736+
cancellation from the outside, and timeouts.
4737+
4738+
```js
4739+
// Deprecated
4740+
async function example() {
4741+
const ac = new AbortController();
4742+
const server = http.createServer(handler);
4743+
server.listen({ port: 3000, signal: ac.signal });
4744+
4745+
await doWork();
4746+
ac.abort();
4747+
}
4748+
```
4749+
4750+
```js
4751+
// Use this instead
4752+
async function example() {
4753+
await using server = http.createServer(handler);
4754+
server.listen(3000);
4755+
4756+
await doWork();
4757+
}
4758+
```
4759+
4760+
```js
4761+
// Deprecated
4762+
async function example() {
4763+
const ac = new AbortController();
4764+
const stream = addAbortSignal(ac.signal, fs.createReadStream(file));
4765+
4766+
await consume(stream);
4767+
ac.abort();
4768+
}
4769+
```
4770+
4771+
```js
4772+
// Use this instead
4773+
async function example() {
4774+
await using stream = fs.createReadStream(file);
4775+
4776+
await consume(stream);
4777+
}
4778+
```
4779+
4780+
```js
4781+
// Deprecated
4782+
async function example() {
4783+
const ac = new AbortController();
4784+
const child = spawn(command, args, { signal: ac.signal });
4785+
4786+
await doWork();
4787+
ac.abort();
4788+
}
4789+
```
4790+
4791+
```js
4792+
// Use this instead
4793+
async function example() {
4794+
using child = spawn(command, args);
4795+
4796+
await doWork();
4797+
}
4798+
```
4799+
47214800
[DEP0142]: #dep0142-repl_builtinlibs
47224801
[DEP0156]: #dep0156-aborted-property-and-abort-aborted-event-in-http
47234802
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf

‎doc/api/net.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,11 @@ Otherwise, if `path` is specified, it behaves the same as
785785
[`server.listen(path[, backlog][, callback])`][`server.listen(path)`].
786786
If none of them is specified, an error will be thrown.
787787

788+
> Using the `signal` option to destroy a long-lived server as a resource cleanup
789+
> mechanism is deprecated. The `signal` option remains appropriate for
790+
> cancellation, externally propagated aborts, and timeouts. See
791+
> [DEP0209](deprecations.md#dep0209-using-abortsignal-to-dispose-of-resources).
792+
788793
If `exclusive` is `false` (default), then cluster workers will use the same
789794
underlying handle, allowing connection handling duties to be shared. When
790795
`exclusive` is `true`, the handle is not shared, and attempted port sharing

‎doc/api/stream.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,6 +3570,10 @@ changes:
35703570
Attaches an AbortSignal to a readable or writable stream. This lets code
35713571
control stream destruction using an `AbortController`.
35723572

3573+
> Stability: 0 - Deprecated. Using [`stream.addAbortSignal()`][] to destroy
3574+
> long-lived stream resources is documentation-only deprecated. See
3575+
> [DEP0209](deprecations.md#dep0209-using-abortsignal-to-dispose-of-resources).
3576+
35733577
Calling `abort` on the `AbortController` corresponding to the passed
35743578
`AbortSignal` will behave the same way as calling `.destroy(new AbortError())`
35753579
on the stream, and `controller.error(new AbortError())` for webstreams.

0 commit comments

Comments
 (0)