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

Remove promisify-any dependency #20

Closed
jwerre opened this issue Oct 10, 2021 · 18 comments · Fixed by #190
Closed

Remove promisify-any dependency #20

jwerre opened this issue Oct 10, 2021 · 18 comments · Fixed by #190
Labels
dependencies 🔌 Pull requests that update a dependency file on hold 🛑 We will look into it at a later time

Comments

@jwerre
Copy link
Contributor

jwerre commented Oct 10, 2021

Just use util.promisify

@jwerre
Copy link
Contributor Author

jwerre commented Oct 10, 2021

Just realized Bluebird is a dependency of promisify-any. Removing this should probably come before removing Bluebird.

@jankapunkt
Copy link
Member

Also here let's check if tests already cover these cases / functionality enough in order to be on the safe side. I think coverage is very high but there are a few lines missed and you know how Mr. Murphy thinks about this :-)

@HappyZombies HappyZombies added the dependencies 🔌 Pull requests that update a dependency file label Oct 10, 2021
@jankapunkt
Copy link
Member

I think we can start on this after #30 has been merged

@jankapunkt
Copy link
Member

#30 is merged, we can safely start with this one :-)

@jwerre
Copy link
Contributor Author

jwerre commented Oct 13, 2021

I'm looking into this now and noticed some oddities I thought maybe you guys could chime in on. First off, a lot of the tests are returning the wrong value, here generateAccessToken should return a string. For example:

generateAccessToken: sinon.stub().returns({ client: {}, expiresAt: new Date(), user: {} })

should be:

generateAccessToken: sinon.stub().returns('my-access-token')

I believe these were left over from version 2 and never updated.

Second, I'm not sure util.promisify is going to work since it requires a callback function and all the of the methods I looked at don't even have a callback as an argument. We could wrap everything in a new Promise but that could get pretty messy.

You guys have any thoughts on this? How to promisify this:

AbstractGrantType.prototype.generateAccessToken = function(client, user, scope) {
  if (this.model.generateAccessToken) {
    return promisify(this.model.generateAccessToken, 3).call(this.model, client, user, scope)
      .then(function(accessToken) {
        return accessToken || tokenUtil.generateRandomToken();
      });
  }

  return tokenUtil.generateRandomToken();
};

I initinally thought we could do this but it won't work since there is no callback:

AbstractGrantType.prototype.generateAccessToken = function(client, user, scope) {
  if (this.model.generateAccessToken) {
    return require('util').promisify(this.model.generateAccessToken)(client, user, scope)
      .then(function(accessToken) {
        return accessToken || tokenUtil.generateRandomToken();
      });
  }

  return tokenUtil.generateRandomToken();
};

@jankapunkt
Copy link
Member

Yes I ran the tests right now with util.promisify and they all fail due to what you wrote @jwerre

If the functions are simple one-dimensional we could write our own wrapper like so:

const promisify = fn => function (...args) {
  const env = this;
  return new Promise((resolve, reject) => {
    try {
      resolve(fn.call(env, ...args));
    } catch (e) {
      reject(e);
    }
  });
};

I checked a few tests and it works so far but I am not sure if this works for all.

@jwerre
Copy link
Contributor Author

jwerre commented Oct 13, 2021

Yes, that's kind of where I ended up. We could just write our own promisify function. Let me whip up a pseudo function and see what you think.

@jankapunkt
Copy link
Member

@jwerre did you come up with anything? Maybe you open a draft pull request so we can work out the details using the code review?

@jwerre
Copy link
Contributor Author

jwerre commented Oct 14, 2021

@jankapunkt I did but I don't love it. I'm not sure it's better than what is there. I'm going to test it out this morning and see if it works. Will post later today.

@jwerre
Copy link
Contributor Author

jwerre commented Oct 14, 2021

Here... I'll just post what I have so far:

module.exports = (fn, fnArgs) => {

  // I was hoping for something like this but I can't get arguments from the
  // function that is passed in.
  //
  // let lastArg = fn.prototype.arguments.length - 1;
  // let isPromise = typeof fn.prototype.arguments[lastArg] !== 'function';

  // if there is no callback in the arguments, return a promise
  if (!fnArgs.length || typeof fnArgs[fnArgs.length - 1] !== 'function') {
    return fn;
  }

  // if there is a callback warp in promise
  return (...args) => {

    return new Promise((resolve, reject) => {

      fn(...args, (err, result) => {

        if (err) {
          return reject(err);
        }

        resolve(result);

      });

    });

  };

};

So instead of:

return promisify(this.model.generateAccessToken, 3)

...it would be:

return promisify(this.model.generateAccessToken, arguments)

I was hoping to get the arguments from the pass function but I don't think is possible so we'll have to just pass them in with the function.

jwerre added a commit that referenced this issue Oct 14, 2021
- Created `lib/utils/promisify.js`
- Removed promisify any from `lib/grant-types/abstract-grant-type.js`
- Updated AbstractGrantType test at `test/unit/grant-types/abstract-grant-type_test.js`
@jwerre
Copy link
Contributor Author

jwerre commented Oct 14, 2021

@jankapunkt I pushed a promisify branch which you can take a look at. I didn't create a pull request because it's far from done and failing a bunch of test. The only files I really worked on are:

  • lib/utils/promisify.js
  • test/unit/utils/promisify_test.js
  • lib/grant-types/abstract-grant-type.js
  • test/unit/grant-types/abstract-grant-type_test.js

Running either of these test should work fine. Take a look at the code and tell me what you think.

@jwerre
Copy link
Contributor Author

jwerre commented Oct 14, 2021

@jankapunkt @HappyZombies, what would you guys say to removing support for callbacks all together?

@HappyZombies
Copy link
Member

HappyZombies commented Oct 14, 2021

@jwerre I am ok with that, but I believe that'll be out of scope for removing this dependency.

Going to a Promise based approach is definitely the way to go, but would require a lot of work and we need to be careful too. I think this can be something we tackle in a next major version.

We can get started on that, but I really wanna focus on getting out important fixes, administrator work NOW. If bluebird has to stay for a while then that's ok for now.

Once we get our next release out (which I am guessing will be 4.1.0), we can talk about what we want in a version 5.

If removing promisify-any is being too much of a pain, let's put a hold on it for now and get back to it later.

@jankapunkt
Copy link
Member

jankapunkt commented Oct 14, 2021

I agree with @HappyZombies but I will still take a look into it. In the meantime we can further discuss release management

@jwerre
Copy link
Contributor Author

jwerre commented Oct 14, 2021

I agree as well. When we deprecate callbacks we can remove Bluebird and promise-any in one fell swoop so I don't think there is any reason to spend any more time on this.

@HappyZombies HappyZombies added the on hold 🛑 We will look into it at a later time label Oct 14, 2021
@jwerre
Copy link
Contributor Author

jwerre commented Oct 16, 2021

@jankapunkt Are you going to take a look at this, or is this safe to close? #48

@jankapunkt
Copy link
Member

@jwerre let's keep it open until we have a clear plan for #48 but once we have we can safely close this as superceded by #48

@Uzlopak
Copy link
Collaborator

Uzlopak commented Nov 12, 2021

I also had a look into promisify-any. promisify-any is capable of wrapping also generator functions.

Is there any necessity to support generator functions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies 🔌 Pull requests that update a dependency file on hold 🛑 We will look into it at a later time
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants