Skip to content

Commit

Permalink
fix: allow increasing number of listeners in node (#29)
Browse files Browse the repository at this point in the history
Node often shows this warning:

```
(node:33263) MaxListenersExceededWarning: Possible EventTarget memory leak detected. 11 abort listeners added to [AbortSignal]. Use events.setMaxListeners() to increase limit
```

The way round it is to use the `setMaxListeners` function from the `events` module.

Unfortunately returning a `Proxy` object to add the `.clear` function
doesn't work with `setMaxLiseners` and fails with:

```
TypeError: The "eventTargets" argument must be an instance of EventEmitter or EventTarget. Received [AbortSignal]
```

The change here is to just add the `.clear` property to the returned `AbortSignal`.
  • Loading branch information
achingbrain authored Apr 13, 2023
1 parent 03fc226 commit 2c51447
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 19 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@
},
"devDependencies": {
"aegir": "^38.1.8",
"p-defer": "^4.0.0"
"p-defer": "^4.0.0",
"wherearewe": "^2.0.1"
},
"browser": {
"node:events": false
}
}
21 changes: 3 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,8 @@ export function anySignal (signals: Array<AbortSignal | undefined | null>): Clea
}
}

// @ts-expect-error Proxy is not a ClearableSignal
return new Proxy(controller.signal, {
get (target, p) {
if (p === 'clear') {
return clear
}

// @ts-expect-error cannot use string to index target type
const value = target[p]
const signal = controller.signal as ClearableSignal
signal.clear = clear

if (typeof value === 'function') {
return function (...args: any[]): any {
return value.apply(target, args)
}
}

return value
}
})
return signal
}
15 changes: 15 additions & 0 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect } from 'aegir/chai'
import pDefer from 'p-defer'
import { isNode, isElectronMain } from 'wherearewe'
import { anySignal } from '../src/index.js'
const { AbortController } = globalThis

Expand Down Expand Up @@ -141,4 +142,18 @@ describe('any-signal', () => {
// No handlers means there are no events propagated to the composite `signal`
expect(signal).to.have.property('aborted', false)
})

it('should be able to increase max number of listeners on returned signal', async () => {
if (!isNode && !isElectronMain) {
return
}

// @ts-expect-error setMaxListeners is missing from @types/node
const { setMaxListeners } = await import('node:events')
const controllers = [...new Array(5)].map(() => new AbortController())
const signals = controllers.map(c => c.signal)
const signal = anySignal(signals)

setMaxListeners(Infinity, signal)
})
})

0 comments on commit 2c51447

Please sign in to comment.