Skip to content

Commit 25fa21a

Browse files
net: use throwIfAborted and improve server iteration example
Address review feedback on the net/promises API: - Use `signal.throwIfAborted()` for the pre-connect and pre-listen abort checks instead of constructing an AbortError by hand. - Update the `server[Symbol.asyncIterator]()` documentation example to dispatch each connection to a separate async task, with a note that awaiting inline serializes connections. Refs: #21482 Assisted-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Ethan Arrowood <ethan@arrowood.dev>
1 parent 84ae422 commit 25fa21a

2 files changed

Lines changed: 20 additions & 14 deletions

File tree

doc/api/net.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -468,18 +468,31 @@ to be consumed with `for await...of` as an alternative to the [`'connection'`][]
468468
event. Iteration ends when the server emits [`'close'`][], and rejects if the
469469
server emits [`'error'`][].
470470

471+
The loop only advances to the next connection once the current iteration's body
472+
has finished awaiting, so connection handling should be dispatched to a separate
473+
async task rather than awaited inline. Otherwise connections are serialized:
474+
each one waits for the previous to be fully handled.
475+
471476
```mjs
472477
import { createServer } from 'node:net';
473478

474479
const server = createServer().listen(8124);
475-
for await (const socket of server) {
480+
481+
async function handleConnection(socket) {
482+
// ...handle the connection, awaiting as needed.
476483
socket.end('hello world!');
477484
}
485+
486+
for await (const socket of server) {
487+
// Dispatch handling to a separate task so the loop keeps accepting
488+
// connections instead of serializing them.
489+
handleConnection(socket);
490+
}
478491
```
479492

480-
Connections are buffered while the loop body is busy; the server does not stop
481-
accepting them, so a consumer that is slower than the connection rate can buffer
482-
without bound. Use [`server.maxConnections`][] to bound concurrency.
493+
The server does not stop accepting connections while the loop body runs, so a
494+
consumer slower than the connection rate can buffer them without bound. Use
495+
[`server.maxConnections`][] to bound concurrency.
483496

484497
### `server.getConnections(callback)`
485498

@@ -2343,9 +2356,7 @@ with `for await...of` (see `server[Symbol.asyncIterator]()`).
23432356
import { listen } from 'node:net/promises';
23442357

23452358
const server = await listen({ port: 8124 });
2346-
for await (const socket of server) {
2347-
socket.end('hello world!');
2348-
}
2359+
console.log('listening on', server.address().port);
23492360
```
23502361

23512362
[IPC]: #ipc-support

lib/internal/net/promises.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const {
55
validateAbortSignal,
66
validateObject,
77
} = require('internal/validators');
8-
const { AbortError } = require('internal/errors');
98
const { kEmptyObject } = require('internal/util');
109

1110
// Lazily loaded to avoid a require cycle with the `net` module, which exposes
@@ -24,9 +23,7 @@ async function connect(...args) {
2423
const { signal } = options;
2524
if (signal !== undefined) {
2625
validateAbortSignal(signal, 'options.signal');
27-
if (signal.aborted) {
28-
throw new AbortError(undefined, { cause: signal.reason });
29-
}
26+
signal.throwIfAborted();
3027
}
3128

3229
// Strip the signal so the socket does not also install its own abort
@@ -49,9 +46,7 @@ async function listen(options = kEmptyObject) {
4946
const { signal, connectionListener } = options;
5047
if (signal !== undefined) {
5148
validateAbortSignal(signal, 'options.signal');
52-
if (signal.aborted) {
53-
throw new AbortError(undefined, { cause: signal.reason });
54-
}
49+
signal.throwIfAborted();
5550
}
5651

5752
const lazy = lazyNet();

0 commit comments

Comments
 (0)