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

Fix #7340 by correclty computing function name for push event #7341

Merged
merged 4 commits into from
Apr 13, 2021

Conversation

percypyan
Copy link
Contributor

@percypyan percypyan commented Apr 12, 2021

New Pull Request Checklist

Issue Description

Related issue: #7340

Approach

First create a failing test to demonstrate the issue described by #7340. Then simply replace the update of the argument message by the use of the newly created res object.

TODOs before merging

  • Add test cases
  • Add entry to changelog

percypyan added 2 commits April 12, 2021 16:01
If any delay occurs after "message.event" assignation in
LiveQueryServer._onAfterSave, the next subscription or request with a different
event might overwrite it, and by that using the wrong "push" function name.
This prevent computing function name from a
incorrect event if multiple subscriptions override
one by one the message.event.
@codecov
Copy link

codecov bot commented Apr 12, 2021

Codecov Report

Merging #7341 (f7e6d71) into master (45d00ce) will decrease coverage by 0.00%.
The diff coverage is 100.00%.

❗ Current head f7e6d71 differs from pull request most recent head d9cd5ff. Consider uploading reports for the commit d9cd5ff to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #7341      +/-   ##
==========================================
- Coverage   93.91%   93.90%   -0.01%     
==========================================
  Files         181      181              
  Lines       13194    13193       -1     
==========================================
- Hits        12391    12389       -2     
- Misses        803      804       +1     
Impacted Files Coverage Δ
src/LiveQuery/ParseLiveQueryServer.js 95.32% <100.00%> (-0.02%) ⬇️
src/batch.js 91.37% <0.00%> (-1.73%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 45d00ce...d9cd5ff. Read the comment docs.

@percypyan
Copy link
Contributor Author

@mtrezza PostgreSQL 13 CI is failing, but I can't understand why...

@percypyan
Copy link
Contributor Author

Also the faulty code has been merge to master on February 2021, but the last release as been made on December 2020... That is kind of weird. How can I have this code on my server if no release has been made since the change 🤔 ?

@mtrezza
Copy link
Member

mtrezza commented Apr 12, 2021

Thanks for this PR!

No worries, these are known faulty tests, it's one or multiple Postgres tests. I restarted the tests.

@dplewis is already working on a PR to fix the faulty Postgres tests.

@@ -944,7 +1021,7 @@ describe('ParseLiveQueryServer', function () {
expect(toSend.object).toBeDefined();
expect(toSend.original).toBeDefined();
done();
}, jasmine.ASYNC_TEST_WAIT_TIME);
}, ASYNC_TEST_WAIT_TIME);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are the timeouts changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no timeout before: the variable was undefined. As promises are all mocked with instant resolution, we can remove it completely. I only have replaced those by a small timeout to ensure that tested process were fully executed before expecting anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, if it was undefined, is there maybe another issue that you have discovered? Maybe that is also why some tests are flaky.

@dplewis any ideas? You recently looked into the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've searched for other usage of jasmine.ASYNC_TEST_WAIT_TIME in the project, if found none.
This is only in this file :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked as much as I can, I only found Promise.resolve/Promise.reject, so no delay applied. But it's certainly safer to have 20-100ms of waiting time to be sure everything is completed.

I had some hard time to navigate through mocks, so I might have miss something!

Copy link
Member

@mtrezza mtrezza Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. It's probably also safer to set the timeout on a file basis rather than globally, because tests may require different timeouts and changes on a global level may cause flaky tests.

@percypyan
Copy link
Contributor Author

@mtrezza Do I need to do something more or we just need an other review?

@@ -753,7 +763,7 @@ describe('ParseLiveQueryServer', function () {
setTimeout(function () {
expect(client.pushDelete).toHaveBeenCalled();
done();
}, jasmine.ASYNC_TEST_WAIT_TIME);
Copy link
Member

@mtrezza mtrezza Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think you could rewrite these timed blocks to use async/await instead of being nested?

I know that goes a bit beyond the scope of this PR, but it would certainly make the tests easier to read. So instead of these nests we would just do:

await new Promise(resolve => setTimeout(resolve, ASYNC_TEST_WAIT_TIME));

or maybe even shorter if you want to use a method:

await timeout(ASYNC_TEST_WAIT_TIME);

CHANGELOG.md Outdated
@@ -130,6 +130,7 @@ ___
- Fix file upload issue for S3 compatible storage (Linode, DigitalOcean) by avoiding empty tags property when creating a file (Ali Oguzhan Yildiz) [#7300](https://github.com/parse-community/parse-server/pull/7300)
- Add building Docker image as CI check (Manuel Trezza) [#7332](https://github.com/parse-community/parse-server/pull/7332)
- Add NPM package-lock version check to CI (Manuel Trezza) [#7333](https://github.com/parse-community/parse-server/pull/7333)
- Send correct events when multiple subscriptions exists for a class, and that the events triggered are differents [#7341](https://github.com/parse-community/parse-server/pull/7341)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please change to:

Fix incorrect LiveQuery events triggered for multiple subscriptions on the same class with different events

Does that make sense?

}, ASYNC_TEST_WAIT_TIME);
});

it('can handle object multiple commands which matches some subscriptions', async done => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make this more specific, how about:

sends correct events for object with multiple subscriptions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm not very good in English when it comes to that kind of things 😂

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not easy to describe for me neither 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ah you're reassuring me!

@percypyan
Copy link
Contributor Author

All done @mtrezza!

@@ -9,6 +9,16 @@ const queryHashValue = 'hash';
const testUserId = 'userId';
const testClassName = 'TestObject';

const ASYNC_TEST_WAIT_TIME = 100;

function resolveAfter(result, msTimeout) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we shorten this to

const timeout = t => new Promise(resolve => setTimeout(resolve, t || ASYNC_TEST_WAIT_TIME));

then just use

await timeout();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, do you prefer timeout instead of resolveAfter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, is there a util file were this method should be moved? Or should we keep it file-specific?

Copy link
Member

@mtrezza mtrezza Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, do you prefer timeout instead of resolveAfter?

Yes because this doesn't resolve anything anymore.

Also, is there a util file were this method should be moved? Or should we keep it file-specific?

Good idea, we have a helper.js for global test declarations. I would however not move the default value, because we risk that someone changes that value in the future and suddenly tests become flaky or have a higher timeout than necessary.

So maybe move this into helper:

jasmine.timeout = t => new Promise(resolve => setTimeout(resolve, t));

then just use this on file level

const timeout200 = jasmine.timeout(200); // or whatever the number

then call

await timeout();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mtrezza changes done

Copy link
Member

@mtrezza mtrezza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for this PR, now let's wait for another reviewer to approve and it's ready for merge.

@mtrezza mtrezza requested a review from dplewis April 13, 2021 15:07
Copy link
Member

@davimacedo davimacedo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@davimacedo davimacedo merged commit 87dcd23 into parse-community:master Apr 13, 2021
Arul- pushed a commit to Arul-/parse-server that referenced this pull request Apr 20, 2021
…h event (parse-community#7341)

* Add a failing test for issue parse-community#7340

If any delay occurs after "message.event" assignation in
LiveQueryServer._onAfterSave, the next subscription or request with a different
event might overwrite it, and by that using the wrong "push" function name.

* Remove updade of message and use res.event instead

This prevent computing function name from a
incorrect event if multiple subscriptions override
one by one the message.event.

* Update CHANGELOG.md

* Replace setTimeout by async/await expressions
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 5.0.0-beta.1

@parseplatformorg parseplatformorg added the state:released-beta Released as beta version label Nov 1, 2021
@mtrezza mtrezza mentioned this pull request Mar 12, 2022
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 5.0.0

@parseplatformorg parseplatformorg added the state:released Released as stable version label Mar 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state:released Released as stable version state:released-beta Released as beta version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants