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

Extend listener removal in BusHelper #37

Merged
merged 3 commits into from
Feb 19, 2024

Conversation

tuxedoxt
Copy link
Contributor

Hello,

if the intended use of Device.disconnect also is to clean up the remaining event listeners this PR extends this to include the leftover BusHelper._propsProxy event listeners adding a new function BusHelper.removeListeners for this purpose.

This seems to do it for my current issue in #35.

- Adds a clean-up function `removeListeners` that in addition to
  the already existing PropertiesChanged removal on itself
  (in `Device.disconnect`) also removes PropertiesChanged
  event listeners on the _propsProxy object.
- Adds use of this clean-up function in `Device.disconnect`.
@chrvadala chrvadala linked an issue Jul 3, 2022 that may be closed by this pull request
@tuxedoxt
Copy link
Contributor Author

tuxedoxt commented Jul 7, 2022

Bump :)

Any feedback?

@chrvadala
Copy link
Owner

This approach looks better, but I have to try it. I will next weekend, promised.
In the mean time, can you add some unit test?

@ChocolateLoverRaj
Copy link

This seems to do it for my current issue in #35.

@tuxedoxt How did you get the error to stop? I tried using your fork and calling await device.disconnect(), but I still got error.

@mxc42
Copy link
Contributor

mxc42 commented Oct 12, 2022

Related issue, after calling Adapter.devices in a loop once every 5 seconds I start to get (node:4278) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 {"path":"/org/bluez/hci0/dev_6C_EC_26_F4_E4_5C","interface":"org.freedesktop.DBus.Properties","member":"PropertiesChanged"} listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit

This is the code in question, called from a setInterval loop every 5 seconds.

    const devices = await adapter.devices();
    for (let i = 0; i < devices.length; i++) {
        try {

            const device = await adapter.getDevice(devices[i]);
            const name = await device.getName();
            const rssi = await device.getRSSI();
            await device.disconnect();
            ...

I've tried the changes in this PR but they didn't affect the error.

@tuxedoxt
Copy link
Contributor Author

@tuxedoxt How did you get the error to stop? I tried using your fork and calling await device.disconnect(), but I still got error.

I ended up using this change combined with dbusjs/node-dbus-next#110

Since none got merged still using the forked versions explicitly binding the github urls in package.json where needed.

Example, temporary forked node-ble which has this change and a reference to forked dbus-next change:

"node-ble": "git+https://github.com/tuxedoxt/node-ble.git#match-and-event-leak-fixes",

@chrvadala chrvadala linked an issue Oct 28, 2022 that may be closed by this pull request
Copy link
Owner

@chrvadala chrvadala left a comment

Choose a reason for hiding this comment

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

I confirm that exists a memory leak, but the provided fix may introduce a different bug.

removeListeners () {
this.removeAllListeners('PropertiesChanged')
if (this._propsProxy !== null) {
this._propsProxy.removeAllListeners('PropertiesChanged')
Copy link
Owner

Choose a reason for hiding this comment

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

@tuxedoxt I understand that you want to delete this listener because it generate a memory leak, but I think that if you do this in this way, you creates a different bug.
What if the user connects again this device? No code line will subscribe again on 'PropertiesChanged' events, so the library will not work correctly.

I think that this bug requires a different fix.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the feedback. I see what you mean.

As I see it, additionally setting

this._ready = false

should make _prepare reattach listener. However also does other things, like assigns completely new _propsProxy and _ifaceProxy objects. Would more clean-up be needed there or is this feasible?

@coveralls
Copy link

Coverage Status

Coverage: 95.783% (-0.05%) from 95.833% when pulling 1855c3b on tuxedoxt:device-listener-cleanup into eb20e9c on chrvadala:main.

@derwehr
Copy link
Contributor

derwehr commented Apr 14, 2023

Any chance this will get merged soon?

@tuxedoxt
Copy link
Contributor Author

Another bump :)

@chrvadala

@Leafgard
Copy link

@chrvadala chrvadala merged commit 6611591 into chrvadala:main Feb 19, 2024
@chrvadala
Copy link
Owner

Released with v1.10

nmasse-itix pushed a commit to Demo-AI-Edge-Crazy-Train/node-ble that referenced this pull request Apr 29, 2024
* Extend listener removal in BusHelper

- Adds a clean-up function `removeListeners` that in addition to
  the already existing PropertiesChanged removal on itself
  (in `Device.disconnect`) also removes PropertiesChanged
  event listeners on the _propsProxy object.
- Adds use of this clean-up function in `Device.disconnect`.

* Fix re-use after listener removal in BusHelper

* Add test cases for BusHelper.removeListeners
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Device dbus "match" leak Device (properties) event listener leak
7 participants