-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[3.0] Report and extend test cases for the new async behaviors #13052
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
Conversation
…ns and persistence
…t to match 2.x behavior" This reverts commit 47ed012.
Hello @nachocodoner, just want to commend you on the careful and detailed explanation you provide in your PRs, along with the annotated screenshots. What a great way to share and spread knowledge! Please keep on doing it 👏 👏 |
@harryadel: Appreciate it! 😊 I try to do the best to comprehend the core and complexities of every component I engage with, consistently sharing my insights with the community in the form of text and images. Regarding this complex issue, after thorough exploration and team discussions, it appears challenging. Considering the inherent async nature in Meteor 3.x, closing this PR might be necessary. Exploring alternatives like I'll provide a detailed explanation, ensuring the community is informed about this shift in approaching async methods and operations. |
I'd like to clarify the differences observed between the behaviors of Meteor 2.x and 3.x versions through examples. The evolution in handling asynchronous operations in 3.x requires adjustments in client and server-side executions. I'll illustrate this with practical scenarios, including ensuring code isomorphism, particularly in testing. Given the following Meteor method and collection described on client and server. const Greetings = new Mongo.Collection('greetings');
Meteor.methods({
greetUser: function(name) {
Greetings.insert({ doc: { userId: Meteor.userId(), name } });
return "Hello, " + name + "!";
}
}); Meteor 2.xIn Meteor 2.x, when calling the method with Meteor.call('greetUser', 'John', function(error, result) {
if (error) {
console.error("Error:", error.reason); // 🔴 Server ended with error
} else {
console.log("Result:", result); // 🟢 Server ended with success
}
Greetings.findOne({ name: 'John' }); // 🗑️ Data is NOT available
});
// 🔵 Client simulation
Greetings.findOne({ name: 'John' }); // 🧾 Data is available (Optimistic-UI) In this example above:
Meteor 3.xIn Meteor 3.x, when calling the method with serverPromiseDefault / serverPromise (await)try {
await Meteor.callAsync('greetUser', 'John');
// 🟢 Server ended with success
} catch(e) {
console.error("Error:", error.reason); // 🔴 Server ended with error
}
Greetings.findOne({ name: 'John' }); // 🗑️ Data is NOT available Default / serverPromise (then/catch)await Meteor.callAsync('greetUser', 'John')
.then(result => {
console.log("Result:", result); // 🟢 Server ended with success
})
.catch(error => {
console.error("Error:", error.reason); // 🔴 Server ended with error
});
Greetings.findOne({ name: 'John' }); // 🗑️ Data is NOT available In the examples above the client (🔵) simulation IS NOT handled and instead the server awaits for its result. stubPromiseHowever, when handling stubPromise (await)await Meteor.callAsync('greetUser', 'John').stubPromise;
// 🔵 Client simulation
Greetings.findOne({ name: 'John' }); // 🧾 Data is available (Optimistic-UI) This time, we only manage simulation time, not the server. Client errors can be handled with try/catch. stubPromise and serverPromiseAnother example using both promises. const { stubPromise, serverPromise } = Meteor.callAsync('greetUser', 'John');
await stubPromise;
// 🔵 Client simulation
Greetings.findOne({ name: 'John' }); // 🧾 Data is available (Optimistic-UI)
try {
await serverPromise;
// 🟢 Server ended with success
} catch(e) {
console.error("Error:", error.reason); // 🔴 Server ended with error
}
Greetings.findOne({ name: 'John' }); // 🗑️ Data is NOT available In the example above, we could have handled any client error with try/catch as well. This demonstrates the approach of async/await in Meteor 3.x and how it replicates previous callback and fibers-based behaviors. resolverTypeAdditionally, to enforce the use of const Greetings = new Meteor.Collection('greetUser', { resolverType: 'stub' });
await Greetings.insertAsync({ test: 1 });
// 🔵 Client simulation
Greetings.findOne({ name: 'John' }); // 🧾 Data is available (Optimistic-UI) More details refer to the original PR on the addition of ConclusionWe can't resolve the issue outlined in this PR because it aligns with the expected behavior of the new async approach using promises (3.x), which differs from when we utilized non-standard fibers (2.x). I'll soon merge the PR with new tests covering the behaviors explained above and keep this post for future reference. |
✅ Deploy Preview for v3-meteor-api-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
# Conflicts: # packages/mongo/mongo_livedata_tests.js
Great explanation @nachocodoner. I think the content of this entire PR discussion should be added to this page in the docs. Newcomers can't learn this from a PR, and I don't believe it's useful only for experienced Meteor users. Even if it was, it should still be documented in the official docs 🥁. |
OSS-350
Context
Issue: #13036
A continuation of #12969, which provided a configuration to sort one of the problems on keeping the same behavior on running collection operations on Meteor 3.x in respect of Meteor 2.x. That fix resulted to be like a workaround, and hopefully with this new iteration is completely fixed.
Reproduction
Thanks to @bhunjadi I was able to understand and debug further the core flow about this issue and realized how Meteor 2.x and 3.x behaves distinctly in the process to run a collection operation.
In Meteor 2.x:
insertAsync
replace: undefined
messageIn Meteor 3.x:
insertAsync
replace: undefined
messageIt is depicted on the next attachment:
This PR aims to ensure 3.x behavior matches the 2.x behavior. Data won't be persisted as the original github issue states (#13036), that is not the behavior on Meteor 2.x . For that, in Meteor, you need to fetch via subscription or a method, or directly use the local collection for inserting. Anyway, matching this behavior in both versions will also fix tests afftected by the community packages, since they expect the data to be available in the same run cycle that the op happened.
Fix