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

Prevent deadlocks on components and locale updates #15535

Merged
merged 1 commit into from Jan 25, 2023

Conversation

petersg83
Copy link
Contributor

What does it do?

It uses sequential updates instead of Promise.all to avoid deadlocks

Why is it needed?

Because otherwise it can prevent to create a new locale for an entity or to save an entry with components

How to test it?

It's very difficult to test it as the deadlocks are random. Contact @Marc-Roig so he can show you how to :p

Related issue(s)/PR(s)

#15202

@petersg83 petersg83 added source: core:strapi Source is core/strapi package pr: fix This PR is fixing a bug labels Jan 23, 2023
@petersg83 petersg83 added this to the 4.6.0 milestone Jan 23, 2023
@codecov
Copy link

codecov bot commented Jan 23, 2023

Codecov Report

Base: 61.29% // Head: 50.62% // Decreases project coverage by -10.68% ⚠️

Coverage data is based on head (70f188c) compared to base (62e3f93).
Patch coverage: 0.00% of modified lines in pull request are covered.

❗ Current head 70f188c differs from pull request most recent head c02061d. Consider uploading reports for the commit c02061d to get more accurate results

Additional details and impacted files
@@             Coverage Diff             @@
##             main   #15535       +/-   ##
===========================================
- Coverage   61.29%   50.62%   -10.68%     
===========================================
  Files        1355      297     -1058     
  Lines       33498    10474    -23024     
  Branches     6455     2324     -4131     
===========================================
- Hits        20532     5302    -15230     
+ Misses      11143     4272     -6871     
+ Partials     1823      900      -923     
Flag Coverage Δ
back 50.62% <0.00%> (-0.01%) ⬇️
front ?
unit_back 50.62% <0.00%> (-0.01%) ⬇️
unit_front ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...r/server/services/utils/configuration/metadatas.js 9.80% <0.00%> (-0.20%) ⬇️
...admin/src/content-manager/components/Hint/index.js
...n/src/content-manager/components/InputUID/index.js
...ntent-manager/components/PreviewWysiwyg/Wrapper.js
...in/src/content-manager/components/Wysiwyg/index.js
...min/src/utils/isAllowedContentTypesForRelations.js
...ges/MarketplacePage/components/SortSelect/index.js
...rc/content-manager/hooks/useKeyboardDragAndDrop.js
...ore/upload/admin/src/pages/SettingsPage/reducer.js
...dmin/src/content-manager/pages/ListView/actions.js
... and 1049 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@Boegie19
Copy link
Collaborator

Boegie19 commented Jan 24, 2023

users and permisisons also has one don't know if this should be in this pr or a different one?

await Promise.all(
toCreate.map((permissionInfo) =>
strapi.query('plugin::users-permissions.permission').create({ data: permissionInfo })
)
);
},

the #12346 pr also would fix this

@jhoward1994
Copy link
Contributor

There are also some other uses of Promise.all() in the entity-service and i18n plugin:

const componentsToDelete = await Promise.all(
entitiesToDelete.map((entityToDelete) => getComponents(uid, entityToDelete))
);
const deletedEntities = await db.query(uid).deleteMany(query);
await Promise.all(
componentsToDelete.map((compos) => deleteComponents(uid, compos, { loadComponents: false }))
);
// Trigger webhooks. One for each entity
await Promise.all(entitiesToDelete.map((entity) => this.emitEvent(uid, ENTRY_DELETE, entity)));

const migrateBatch = async (entries, { model, attributesToMigrate }, { transacting }) => {
const { copyNonLocalizedAttributes } = getService('content-types');
const updatePromises = entries.map((entity) => {
const updateValues = pick(attributesToMigrate, copyNonLocalizedAttributes(model, entity));
const entriesIdsToUpdate = entity.localizations.map(prop('id'));
return Promise.all(
entriesIdsToUpdate.map((id) =>
strapi.query(model.uid).update({ id }, updateValues, { transacting })
)
);
});
await Promise.all(updatePromises);
};

Could these lead to deadlocks? And if not should we change the syntax anyway for consistency?

Copy link
Member

@nathan-pichon nathan-pichon left a comment

Choose a reason for hiding this comment

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

LGTM as a quick fix.
But I'm persuaded that we should find a way to do ops in parallel as this can decrease performances over huge sets of data. Also, I think we need to mention this point in the release patch note.
Maybe we can put this element to be addressed in the v5 architecture spec process.

@petersg83
Copy link
Contributor Author

Thank you for your reviews!

Yes, we let some Promise.all here and there in the code as we think they are not causing deadlocks. We prefer to wait for users to tell us if they still see deadlocks rather than slowing everything.

We just did another PR on the same part of the code to fix performance issues and it appears... it may also fix the deadlocks! So we would like to first merge #15554 and see if it fixes the deadlocks issues for users before merging this PR :)
In the meantime this PR is on hold then

@petersg83 petersg83 added the flag: don't merge This PR should not be merged at the moment label Jan 24, 2023
@Convly Convly removed this from the 4.6.0 milestone Jan 25, 2023
@petersg83 petersg83 removed the flag: don't merge This PR should not be merged at the moment label Jan 25, 2023
@petersg83 petersg83 added this to the 4.6.0 milestone Jan 25, 2023
@petersg83 petersg83 merged commit c909df5 into main Jan 25, 2023
@petersg83 petersg83 deleted the fix/sequential-requests-deadlock branch January 25, 2023 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: fix This PR is fixing a bug source: core:strapi Source is core/strapi package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants