Skip to content

Commit 81c94a3

Browse files
phryneasruyadorno
authored andcommitted
lib: disable default memory leak warning for AbortSignal
This change sets the default `kMaxEventTargetListeners` property for `AbortSignal` instances to 0, disabling the check per default, to enable users to write isomorphic library code. If desirable, the max event target listeners check can still be enabled for individual `AbortSignal` instances by calling `setMaxListeners` on them. Refs: #54758 PR-URL: #55816 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 381e705 commit 81c94a3

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

doc/api/events.md

+4
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,10 @@ that a "possible EventEmitter memory leak" has been detected. For any single
11711171
`EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()`
11721172
methods can be used to temporarily avoid this warning:
11731173

1174+
`defaultMaxListeners` has no effect on `AbortSignal` instances. While it is
1175+
still possible to use [`emitter.setMaxListeners(n)`][] to set a warning limit
1176+
for individual `AbortSignal` instances, per default `AbortSignal` instances will not warn.
1177+
11741178
```mjs
11751179
import { EventEmitter } from 'node:events';
11761180
const emitter = new EventEmitter();

lib/internal/abort_controller.js

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const {
2828
kResistStopPropagation,
2929
kWeakHandler,
3030
} = require('internal/event_target');
31+
const { kMaxEventTargetListeners } = require('events');
3132
const {
3233
customInspectSymbol,
3334
kEmptyObject,
@@ -165,6 +166,7 @@ class AbortSignal extends EventTarget {
165166
}
166167
super();
167168

169+
this[kMaxEventTargetListeners] = 0;
168170
const {
169171
aborted = false,
170172
reason = undefined,

test/parallel/test-eventtarget-memoryleakwarning.js

+23-11
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ const { setTimeout } = require('timers/promises');
1212
common.expectWarning({
1313
MaxListenersExceededWarning: [
1414
['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
15-
'EventTarget. MaxListeners is 2. Use events.setMaxListeners() ' +
15+
'EventTarget. MaxListeners is 2. Use events.setMaxListeners() ' +
1616
'to increase limit'],
1717
['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
18-
'[MessagePort [EventTarget]]. ' +
19-
'MaxListeners is 2. ' +
20-
'Use events.setMaxListeners() to increase ' +
18+
'[MessagePort [EventTarget]]. ' +
19+
'MaxListeners is 2. ' +
20+
'Use events.setMaxListeners() to increase ' +
2121
'limit'],
2222
['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
23-
'[MessagePort [EventTarget]]. ' +
24-
'MaxListeners is 2. ' +
25-
'Use events.setMaxListeners() to increase ' +
23+
'[MessagePort [EventTarget]]. ' +
24+
'MaxListeners is 2. ' +
25+
'Use events.setMaxListeners() to increase ' +
2626
'limit'],
27-
['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
28-
'[AbortSignal]. ' +
29-
'MaxListeners is 2. ' +
30-
'Use events.setMaxListeners() to increase ' +
27+
['Possible EventTarget memory leak detected. 2 foo listeners added to ' +
28+
'[AbortSignal]. ' +
29+
'MaxListeners is 1. ' +
30+
'Use events.setMaxListeners() to increase ' +
3131
'limit'],
3232
],
3333
});
@@ -65,13 +65,25 @@ common.expectWarning({
6565
mc.port1.addEventListener('foo', () => {});
6666
mc.port1.addEventListener('foo', () => {});
6767
mc.port1.addEventListener('foo', () => {});
68+
}
6869

70+
{
71+
// No warning emitted because AbortController ignores `EventEmitter.defaultMaxListeners`
72+
setMaxListeners(2);
6973
const ac = new AbortController();
7074
ac.signal.addEventListener('foo', () => {});
7175
ac.signal.addEventListener('foo', () => {});
7276
ac.signal.addEventListener('foo', () => {});
7377
}
7478

79+
{
80+
// Will still warn as `setMaxListeners` can still manually set a limit
81+
const ac = new AbortController();
82+
setMaxListeners(1, ac.signal);
83+
ac.signal.addEventListener('foo', () => {});
84+
ac.signal.addEventListener('foo', () => {});
85+
}
86+
7587
{
7688
// It works for EventEmitters also
7789
const ee = new EventEmitter();

0 commit comments

Comments
 (0)