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

App hang when using promises/async on connecting #258

Open
Aykelith opened this issue Jun 23, 2018 · 6 comments
Open

App hang when using promises/async on connecting #258

Aykelith opened this issue Jun 23, 2018 · 6 comments

Comments

@Aykelith
Copy link

I'm using NodeJS 8.11.3 with Monk 6.0.6 and I have the next piece of code:

function monkConnect(url) {
    return new Promise(resolve => {
        resolve(monk(url));
    });
}

await monkConnect("some valid url");

I have tried in so many ways to make this works( using the callback from monk(url), making the function async and calling await on monk, and so many methods) and the code just freeze/hang and nothing happen and I don't know how to resolve it. Please some help.

@szm1
Copy link

szm1 commented Aug 7, 2018

I ran into this problem yesterday as well and have tried all manner of things. I'm not sure if the monk constructor is returning a proper promise. It sets up a bunch of functions on it including a then function:

Manager.prototype.then = function (fn) {
  return new Promise(function (resolve, reject) {
    this.once('open', resolve)
    this.once('error-opening', reject)
  }.bind(this)).then(fn.bind(null, this))
}

However, if mongo isn't actually running when monk tries to connect, it doesn't use the reject function passed into the then function above, it just breaks out and I get an unhandled promise rejection error.

It would be great if this problem could get fixed, because I'm trying to use async/await to wait until monk connects before trying to get some data out of the database, but that's not possible currently.

@nevyn-lookback
Copy link

Monk constructor is indeed not returning a promise at all. It's returning a function that vaguely looks like a promise. Not only that: the promise is also not resolving to the monk instance, so you can't do const db = await monk()!

I would strongly encourage monk's maintainer to either make monk() actually return a real promise and not a make-believe one; or separating connection logic into a connect(): Promise<> function.

A hack meanwhile:

const db = monk(mongoUrl);
await monk(mongoUrl).then(function() {});

If I could also request JS developers everywhere to stop returning type-punned results that look like many different things, and instead be a single value, I'd be very happy :(

@mathieudutour
Copy link
Collaborator

Happy to accept a PR

@nevyn-lookback
Copy link

Sorry for my tone. Had a really bad day. Working on a PR.

@toniov
Copy link

toniov commented Oct 15, 2018

I just want to note that the hack above is creating two connections actually, but we are not getting the second connection instance back, so it's impossible to close (causing the Node process to stay alive even if all the operations are done).

@Darkhogg
Copy link

Darkhogg commented Nov 15, 2019

A year later, this is still a problem, and I don't think there's a solution that doesn't break compatibility.

The only workaround I've been able to use is:

function connect (uri) {
    const db = monk(uri);
    db.then = null;

    return new Promise((accept, reject) => {
      db.once('open', () => accept(db));
      db.once('error-opening', reject);
    });
}

Essentially, remove the then to avoid JS treating it as a then-able (which will cause it to never resolve, because it resolves to itself in a loop forever), then constructing my own promise.

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

No branches or pull requests

6 participants