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

Use native promises #689

Merged
merged 2 commits into from
Jun 2, 2022
Merged

Use native promises #689

merged 2 commits into from
Jun 2, 2022

Conversation

mohd-akram
Copy link
Contributor

No description provided.

@cressie176
Copy link
Collaborator

Thanks @mohd-akram, I'll review shortly

@cressie176 cressie176 self-assigned this May 19, 2022
@@ -286,6 +282,7 @@ class ConfirmChannel extends Channel {
if (err === null) resolve();
else reject(err);
};
if (!this.pending) unconfirmed[index](new Error('channel closed'))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where is this coming from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This does the same as this and was necessary for a test. 'close' is emitted before waitForConfirms is called so it wasn't being handled there. this.pending is set to null when the channel is closed (in Channel._rejectPending) so that's used to check.

Copy link
Collaborator

Choose a reason for hiding this comment

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

this sounds like it could result in memory leaks. when do we dispose of unconfirmed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, I guess. Ostensibly it's disposed in the 'close' handler in lib/channel.js. However, due to the check in the while loop it exits midway (unconfirmed seems to have values of false). I've updated the code to match what's in the 'close' handler.

test/channel.js Outdated
ch._rpc(defs.ChannelOpen, {outOfBand: ''}, defs.ChannelOpenOk, cb);
});
});
async function open(ch) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why make it async?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My understanding of Promise.try is it makes all exceptions, synchronous or asynchronous, to get thrown in .catch. Making the function async does the same thing by wrapping the whole code in a promise.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm confused by how the open was originally being used. There are some cases when then is never called, so the ChannelOpen rpc may execute after the code has continued.

I'm also not sure why Promise.try was required in the first place. ch.allocate can throw a synchronous error, but never does when I run the test suite. If we're uncomfortable with making the function async, then both the following appear to work...

// Decide that Promise.try wasn't necessary to start with
function open(ch) {
  ch.allocate();
  return promisify(function(cb) {
    ch._rpc(defs.ChannelOpen, {outOfBand: ''}, defs.ChannelOpenOk, cb);
  })();
}
// Emulate Promise.try without async
function open(ch) {
  return new Promise((resolve, reject) => {
    try {
      ch.allocate();
      ch._rpc(defs.ChannelOpen, {outOfBand: ''}, defs.ChannelOpenOk, (err, channel) => {
        if (err) return reject(err);
        resolve(channel);
      });
    } catch (err) {
      reject(err);
    }
  })
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

async is redundant if we are returning Promise already, which I believe we are

Copy link
Collaborator

@cressie176 cressie176 May 22, 2022

Choose a reason for hiding this comment

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

In the original code if ch.allocate throws an error while still synchronous, it will be thrown rather than rejected. Promise.try prevents this by wrapping the supplied function in a try/catch and rejecting caught errors. That's the only reason for using Promise.try that I can see, but it doesn't seem to be necessary in this case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've removed the async since it seems unnecessary.

@kibertoad
Copy link
Collaborator

Could you also fix conflicts?

@mohd-akram
Copy link
Contributor Author

Updated.

@cressie176
Copy link
Collaborator

all good @kibertoad?

@cressie176 cressie176 merged commit 5f621ad into amqp-node:main Jun 2, 2022
@cressie176
Copy link
Collaborator

Published in amqplib@0.10.0

Thank you @mohd-akram

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.

3 participants