amqp / rhea-promise

A promisified layer over rhea AMQP client
Apache License 2.0
30 stars 19 forks source link

Fix `MaxListenersExceededWarning` - "disconnected listeners" with `disconnectEventAudienceMap` #78

Open HarshaNalluru opened 3 years ago

HarshaNalluru commented 3 years ago

Description

MaxListenersExceededWarning - "disconnected listeners" - Cause

Fix

TODO

Reference to any GitHub issues

@richardpark-msft @chradek @ramya-rao-a

chradek commented 3 years ago

I started reviewing but have a couple questions and comments.

  1. Is the goal simply to prevent seeing the node.js warning when a lot of listeners are attached to a single emitter? Did we decide we didn't want to increase the limit to a very large number? (Could we even remove the limit entirely?)

I ask because it looks like we're essentially doing what event listener does: store all the callback functions on an emitter into an object we can iterate over. I want to make sure this isn't also due to a real performance issue because from that standpoint the only piece that looks like it would run faster is removing event listeners, it's just now we manage calling the callbacks versus the emitter calling them.

  1. Why is this change limited to session.close()? Should it apply anywhere where a disconnected event is added? (For example, session creation.)
HarshaNalluru commented 3 years ago

Thanks for the comments, @chradek!!!

Why is this change limited to session.close()? Should it apply anywhere where a disconnected event is added? (For example, session creation.)

Not just session creation. Potentially, any "child" that is adding the listeners on the connection object. I had added a TODO in the description too if we decided to go with this solution.

Is the goal simply to prevent seeing the node.js warning when a lot of listeners are attached to a single emitter? Did we decide we didn't want to increase the limit to a very large number? (Could we even remove the limit entirely?)

Great question. That's the idea technically, and this seemed to be the only way I could prevent the addition of too many listeners. We have not decided on increasing/removing the limits.

I ask because it looks like we're essentially doing what event listener does: store all the callback functions on an emitter into an object we can iterate over. I want to make sure this isn't also due to a real performance issue because from that standpoint the only piece that looks like it would run faster is removing event listeners, it's just now we manage calling the callbacks versus the emitter calling them.

That's exactly what I was thinking of too.. while implementing this "supposed fix". I'm also unsure if this fixes things..

Any thoughts, @chradek ?

richardpark-msft commented 3 years ago

@chradek brings up a good point that I hadn't honestly thought about.

In the previous fix, the potential number of registered listeners was one per message (ie, if we were doing "backup" message settlement). So it'd be difficult for us to really know what the cap is, but theoretically it could be something like 2000+.

This particular one seems like it's centered around links - if that's the case then that number is likely to be very low (ie, I think even in our tests we ended up having 11 total (1 over the limit) so we're probably not in bad shape there to just bump up the max listeners.

We actually already do bump up the limit to a much higher default than I anticipated for Senders: https://github.com/Azure/azure-sdk-for-js/blob/869a72352f16963c243516106334c5f3cccc2e67/sdk/servicebus/service-bus/src/core/messageSender.ts#L295

I would think that the simplicity of just using the built-in default rather than having something custom would outweigh potential efficiency gains, IMO.

HarshaNalluru commented 3 years ago

TODO: Have a parallel PR to bump the listeners limit to a higher number.