DDP shows method result, but await Meteor.callAsync just hangs

Meteor 3.0.4, React 18.3.1, using hooks

Typical situation where a button click event runs a function, which calls a method:
<button onClick={() => save()}>Save</button>
Then

const save = async () => {
  try {
    console.log('Calling method');
    await Meteor.callAsync('save', update);
    console.log('Done');
  }
  catch (error) {
    console.log(error);
  }
}

What’s crazy is that I can click that button over and over, and sometimes it works fine, sometimes it hangs on the ‘await’ line, and I never see the ‘Done’ message. It just hangs.

When I look at the DDP traffic in the Meteor Dev Tools, I see the method being called, and a split second later I see the method’s return (which I would expect to resolve the Meteor.callAsync promise and move on to the console.log(‘Done’)).

I know this isn’t a lot of detailed information about my issue, but I’m wondering if anyone has noticed a similar issue after upgrading to Meteor 3.

I see in the 3.1 changelog:

  • Solve remaining issues with Top Level Await and Reify

And wondering if this particular item might be related to unreliable promise resolution in Meteor.callAsync

The way you wrote the example, you are awaiting for a result that you don’t actually use. Does this help for Optimistic UI? I never use stubs so I am not sure what is the intent in your code.

How about this?

const save = () => {
  Meteor.callAsync('save', update)
    .then(res => {
      // do something with res or don't use .then() if you are not expecting anything to return
       console.log('Done'))
     }
    .catch(err => console.log(err))
}

Thanks for your reply. I just outlined roughly what’s going on. I do, in fact, assign the awaited value to a variable an use it after (of course, when the issue manifests, execution never passes below the await).

I’m currently rolling back to meteor 2.16, with all other code the same. I think this might help me determine if the issue is fundamentally something related to meteor3, or if it’s something in my code. I’ll report back here when I know.

I downgraded to meteor 2.16, and I’m running the identical code as before, and it no longer hangs while awaiting a meteor method call.

This suggests that there is an issue with meteor 3 and async/await on method calls. Once things settle over here, I’m going to try upgrading to meteor 3.1 (whose changelog states the fixing of some issue related to top-level await), and will report here if the issue is resolved in that version.

If you can create a simple reproduction code that can exhibit the behavior, that can immensely help check what’s happening.

I wish I could, but the tricky part is that the issue only happens in our production environment, and it seems to be worse during the day (higher traffic/load). What makes even less sense, is that it looks like a client-side-only issue, because the server clearly successfully completing the method call, and it’s doing so quite quickly (~50ms)…we see this in our server logs, and it’s confirmed client size in the DDP dev tools.

Edit: I should clarify that this never happens in our staging environment, which is an architectural/infrastructural clone of production.

did you try to add this.unblock() to your method?

@minhna @pacodekumite we’re seeing something similar only in our production-like environment (we’re upgrading to Meteor 3)

How did you solve this?
We’re about to test putting this.unblock() but wondering if you had found out anything else?

Update: this.unblock() seems to resolve the issue, but this is not an ideal solution - anyone know why this is happening?

Thanks for the update. We had to rollback to meteor 2.16 in a rush to get our production environment functional. So I didn’t have a chance to try this.unblock().

I’m curious…where exactly did you put this.unblock() ? Is it just at the start of the meteor method that hangs?

We’ve put it all the way down the callstack. That said, this is really disconcerting :frowning: Not sure if someone from the core Meteor team could help out here please?

More info:

  • We turned oplog OFF and could not replicate the error (we’re not 100% sure of this, but this seems to be the case for a bunch of tests we ran).
  • we found this post Methods "hanging" not returning - #12 by bartoftutormundi and running Meteor.connection._stream.reconnect({_force: true}); seems to fix it… well actually this is not a viable change… it’s just more info that seems to reconnect the client (browser) back to the server and it gets the result of the method callback.

Note when the problem exists in the client and I type in Meteor.status() into the console Meteor.status().connected is true … run the reconnect/force above seems to blast through this. So the client seems to think it’s still connected but the server seems to have disconnected.

Update - just came across Race condition can leave mongo oplog observe driver stick in phase FETCHING · Issue #13599 · meteor/meteor · GitHub we are going to try Meteor 3.2 beta to see if this resolves it

Update 2 - we’re not seeing the issue with Meteor 3.2 beta (yet - I hope this solves this).

1 Like

@adamginsburg
Let me just say “thank you” for your impressive detective work. I’m eagerly awaiting any update regarding Meteor 3.2. I was always sort of hoping that the issue would resolve itself uptream.