-
-
Notifications
You must be signed in to change notification settings - Fork 347
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 slowness when adding user to workspace #1205
FIX slowness when adding user to workspace #1205
Conversation
9f8f09d
to
1d4498f
Compare
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.
Hmm, there seem to exist tests that don't pass and that may be related to your changes:
https://github.com/gristlabs/grist-core/actions/runs/11103855934/job/30846705667?pr=1205#step:17:2848
Can you fix it? Or provide feedback and tell us whether these are just instabilities? (in such case, it would be more convenient to have tests that pass in the CI)
Can you rebase and try again. I can see other PRs are passing now. |
2458ae5
to
286bf75
Compare
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.
Migration looks good. But have you checked those build errors, it looks connected to those changes.
@hexaltation I see some access tests are failing, I think this is caused by this PR, but if it isn't or you have some problems in fixing them, let me know. |
Hello @berhalak, I'm trying to fixing it. |
85fca2d
to
2279bd9
Compare
Hello @berhalak, All tests are now passing. :) |
Hi @hexaltation, Yes, all looks good. Consider this accepted, we just need to carefully schedule merging this one as it contains migration. |
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.
Content looks ok! Thanks for dealing with this @hexaltation. The migration is pretty harmless, but it would still be good to exercise upgrades and downgrades by updating:
grist-core/test/gen-server/migrations.ts
Lines 53 to 59 in c783a4f
const migrations = [Initial, Login, PinDocs, UserPicture, DisplayEmail, DisplayEmailNonNull, | |
Indexes, Billing, Aliases, TeamMembers, FirstLogin, FirstTimeUser, | |
CustomerIndex, ExtraIndexes, OrgHost, DocRemovedAt, Prefs, | |
ExternalBilling, DocOptions, Secret, UserOptions, GracePeriodStart, | |
DocumentUsage, Activations, UserConnectId, UserUUID, UserUniqueRefUUID, | |
Forks, ForkIndexes, ActivationPrefs, AssistantLimit, Shares, BillingFeatures, | |
UserLastConnection, ActivationEnabled, Configs]; |
It would also be important to rebase against latest main
so existing migrations are up to date, and to make the timestamp in the name of the migration file be chronologically after any existing migration if it happens to come before another.
592b4a6
to
12cfb98
Compare
Thanks @paulfitz for your review |
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.
Looks good, thank you.
.select('user') | ||
.from(User, 'user') | ||
.leftJoinAndSelect('user.logins', 'logins') | ||
.where('email IN (:...emails)', {emails: normalizedEmails}); |
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.
@hexaltation is it possible for the list of emails to be empty? We're seeing a failure when running against postgres. Not sure yet if this is the code causing it, might not be, but the error message is of the form you can get with an empty in list:
zing=> SELECT 1 WHERE 1 IN ();
ERROR: syntax error at or near ")"
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.
Hello @paulfitz
As far as I understand the code emails
come from a delta in users lists of :
- orgs
- workspaces
- documents
- billing access
As it a delta, I think that initiating update of one of this four against an empty delta should not occur.
May be we have to fix the following API routes to gently fail with bad request
on empty deltas ?
- PATCH '/api/orgs/:oid/access'
- PATCH '/api/workspaces/:wid/access'
- PATCH '/api/docs/:did/access'
or in doom.ts for updating Billing Accounts.
What do you think about that ?
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.
Hello again @paulfitz!
After discussion with @hexaltation, we are working on something we hope that it would fix the issue.
Especially we found a case where delta.users
is an empty object.
We'll keep you inform about our progress or if we still have questions.
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.
Thanks @fflorent, @hexaltation ! I think reasonable behavior to mimic here is SQLite's, where IN ()
simply matches nothing (and is not a syntax error). This could be done in the code by skipping the query if the where clause will be trying to filter for the the empty set of emails.
const emailUsers = await Promise.all( | ||
emails.map(async email => await this.getUserByLogin(email, {manager: transaction})) | ||
); | ||
const existingUsers = await this.getExistingUsersByLogin(emails, transaction); |
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 have the purpose to replace the await Promise.all()
around a map in previous implementation.
It seems that there were some race condition between the getUserByLogin
callBacks sharing the same transaction locked the DB from time to time.
The new implementation hopes to avoid this concurrency inside the transaction.
.select('user') | ||
.from(User, 'user') | ||
.leftJoinAndSelect('user.logins', 'logins') | ||
.where('email IN (:...emails)', {emails: normalizedEmails}); |
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.
Hello @paulfitz
As far as I understand the code emails
come from a delta in users lists of :
- orgs
- workspaces
- documents
- billing access
As it a delta, I think that initiating update of one of this four against an empty delta should not occur.
May be we have to fix the following API routes to gently fail with bad request
on empty deltas ?
- PATCH '/api/orgs/:oid/access'
- PATCH '/api/workspaces/:wid/access'
- PATCH '/api/docs/:did/access'
or in doom.ts for updating Billing Accounts.
What do you think about that ?
Context
On French administration we can experience instances not beeing able to add users to workspaces due to long queries, and never ending queries.
Proposed solution
e26673e
To fix this issue we propose the same strategy than in #824.
Splitting the query in to simpler queries to gather informations about workspace and organization.
bd43d12
We also propose to remove the promisyfyAll around iteration of getUsers queries.
During local test, it seems to be the main culprit.
The ForEach iteration launches asynchonously many queries recycling the same transaction. Sometime the transaction never ended.
3c6388c
Cause the newly added function getExistingUsersByLogin uses a WHERE on logins.email a INDEX is added to allow fastest queries.
Related issues
FIXES #1005
Has this been tested?