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

[3.0] insertAsync on client won't persist local document #13036

Open
bhunjadi opened this issue Feb 27, 2024 · 2 comments
Open

[3.0] insertAsync on client won't persist local document #13036

bhunjadi opened this issue Feb 27, 2024 · 2 comments
Labels
Milestone

Comments

@bhunjadi
Copy link

Description / reproduction

Please check this failing test: https://github.com/bhunjadi/meteor/blob/795e61aff0c191257937c07eccad7438b2394de4/packages/mongo/allow_tests.js#L1164

Run the test with:

./meteor test-packages mongo

After insertAsync, client doesn't have the document in local collection anymore.

I first observed this when updating meteor-collection-hooks for Meteor 3.0. Here is the failing test.

Notes:

  • Server-side test is working.
  • If you leave out removeAsync, it still fails
  • I'm getting this error in the console: "Method stub (/test_again/insertAsync) took too long and could cause unexpected problems. Learn more at https://github.com/zodern/fix-async-stubs/#limitations"

Debugging:

I noticed that local document exists briefly and it gets deleted.
It seems to me this is because additional event is triggered which removes the document.

What happens is that collection.update method is called with replace msg.
If you look in collection.js the replace value will be undefined, which will trigger the removal of the document couple of lines below.

 if (msg.msg === 'replace') {
  var replace = msg.replace; // will be undefined
  if (!replace) {
    // we'll end up here
    if (doc) self._collection.remove(mongoId);
  } else if (!doc) {
    self._collection.insert(replace);
  } else {
    // XXX check that replace has no $ ops
    self._collection.update(mongoId, replace);
  }
  return;
}

Why it is undefined? Because of this line in minimongo/local_collection.

prepareInsert(doc) {
    ...
    // Here we only set id, but without document. 
    this._saveOriginal(id, undefined);
    this._docs.set(id, doc);

    return id;
  }

I also observed that adding resolverType: 'stub' fixes the test.

const coll = new Mongo.Collection('test_again', {
  resolverType: 'stub'
});

Version
Forked release-3.0 repo

Last version where the problem did not occur
n/a (there was no insertAsync on client)

OS
WSL2 (2.0.14), Ubuntu 22.04.4 LTS
Kernel: 5.15.133.1-microsoft-standard-WSL2

Expected behavior
Document should be in local collection.

Actual behavior
Document is not persisted in local collection.

@nachocodoner
Copy link
Member

nachocodoner commented Mar 1, 2024

Thank you for your detailed report.

In Meteor 3.x, a distinction exists between stub and server promises. The former handles client simulation and minimongo population, while the latter solely manages success or error on the server call without populating the data in minimongo. The data is persisted on the server in both.

The resolverType option offers stub and server values.

Yes, resolverType was introduced recently to cover this fix. There is more information about this configuration on this PR, #12969

I would say we could persue this behavior and making it persistant on use server promise, but it has not been an easy task. I would like to test though some of the debugging points you mentioned.

However, the best I can say for now is the usage of resolveType as stub on those scenarios where you care about data present on the client, or rely on methods and subscriptions to read the data back into the client if you decide to use the server approach.

@nachocodoner
Copy link
Member

Please, refer to this comment to understand the nature of the new async approach using promises in comparison on how was handled on previous Meteor versions.

In this specific issue you must use resolveType: 'stub' which handle properly the stub behaviors on running collection operations and will keep isomorphic code on your tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants