-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Conversation
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 Report
@@ 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
Continue to review full report at Codecov.
|
@mtrezza PostgreSQL 13 CI is failing, but I can't understand why... |
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 🤔 ? |
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. |
spec/ParseLiveQueryServer.spec.js
Outdated
@@ -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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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.
@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); |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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?
spec/ParseLiveQueryServer.spec.js
Outdated
}, ASYNC_TEST_WAIT_TIME); | ||
}); | ||
|
||
it('can handle object multiple commands which matches some subscriptions', async done => { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 😂
There was a problem hiding this comment.
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 😄
There was a problem hiding this comment.
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!
All done @mtrezza! |
spec/ParseLiveQueryServer.spec.js
Outdated
@@ -9,6 +9,16 @@ const queryHashValue = 'hash'; | |||
const testUserId = 'userId'; | |||
const testClassName = 'TestObject'; | |||
|
|||
const ASYNC_TEST_WAIT_TIME = 100; | |||
|
|||
function resolveAfter(result, msTimeout) { |
There was a problem hiding this comment.
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();
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mtrezza changes done
There was a problem hiding this 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…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
🎉 This change has been released in version 5.0.0-beta.1 |
🎉 This change has been released in version 5.0.0 |
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 createdres
object.TODOs before merging