Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes EventEmitter leak in AudioService related to _resetNoDataInterval #12

Merged
merged 2 commits into from
Sep 21, 2022

Conversation

chooper
Copy link
Contributor

@chooper chooper commented Aug 19, 2022

Fixes EventEmitter leak in AudioService related to _resetNoDataInterval

Summary

Fixes an EventEmitter leak in AudioService by preventing the _resetNoDataInterval callback from being registered multiple times.

Motivation

In my current setup, silence detection kicks in to restart the mic instance periodically. This has been fine for my use case; however, after a small number of those, I get warnings about an EventEmitter leak.

note: for testing, I set NO_DATA_INTERVAL_SEC to 1 and set inputDevice in the config to something that didn't exist

$ node --trace-warnings index.js --debug
...
Aug-18-2022 21:54:10 alert : No Mic Data for 1 Seconds
Aug-18-2022 21:54:10 warning : Restarting mic instance
Aug-18-2022 21:54:10 alert : Mic Instance Has STOPPED
Aug-18-2022 21:54:10 info : Mic Instance Has Started
(node:9976) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 data listeners added to [IsSilence]. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:389:17)
    at IsSilence.addListener (events.js:405:10)
    at IsSilence.Readable.on (_stream_readable.js:873:35)
    at AudioService.onData (/home/pi/src/fd-tone-notify/service/AudioService.js:55:30)
    at AudioService.listenForMicInputEvents (/home/pi/src/fd-tone-notify/service/AudioService.js:63:14)
    at AudioService.restart (/home/pi/src/fd-tone-notify/service/AudioService.js:25:14)
    at Timeout._onTimeout (/home/pi/src/fd-tone-notify/service/AudioService.js:49:22)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

Description of problem

In the AudioService class, when a data event hasn't been emitted for NO_DATA_INTERVAL_SEC seconds, AudioService.restart() is invoked.

In the #restart method, the following two lines interact to result in the emitter leak:

        this._rebindDataListenerCallbacks();
        this.listenForMicInputEvents();

In #_rebindDataListenerCallbacks, all callbacks that were registered using the AudioService.onData method are re-applied to the (new) mic instance. More specifically, the callbacks are registered on the mic's audioStream (which is called IsSilence in the library code)

This by itself is fine, but in #listenForMicInputEvents the callback to reset the silence detection interval is registered using the onData method, resulting it in getting re-added to the persistent callback list.

This means that if restart is called for the 10th time, the resetNoDataInterval callback will be re-registered ten times on that turn.

Explanation of solution

Rather than adding #_resetNoDataInterval to a persistent list of callbacks to be re-registered every restart, this PR instead leaves the callback out of the list and instead registers it directly with the mic's audioStream component.

@chooper
Copy link
Contributor Author

chooper commented Aug 19, 2022

Keeping as a draft while I do more testing.

@chooper
Copy link
Contributor Author

chooper commented Aug 30, 2022

I've been running this branch successfully since the 21st with ~40 tone detection events without any restarts. This is ready for review.

@chooper chooper marked this pull request as ready for review August 30, 2022 15:56
@kdolan kdolan self-requested a review September 21, 2022 20:20
@kdolan kdolan added the bug Something isn't working label Sep 21, 2022
Copy link
Contributor

@kdolan kdolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@kdolan kdolan merged commit 97b70b1 into kjdElectronics:main Sep 21, 2022
@chooper chooper deleted the chooper/fix-emitter-leak branch September 26, 2022 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants