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

Resolve per-entity resolvers after receiving a list of records #26575

Merged
merged 4 commits into from
Nov 3, 2020

Conversation

adamziel
Copy link
Contributor

@adamziel adamziel commented Oct 29, 2020

Description

The problem: calling saveEntityRecord() triggers a number of per-entity GET requests:

Zrzut ekranu 2020-10-29 o 17 12 38

The cause is described in #26325:

saveEntityRecord() calls getRawEntityRecord(), which doesn't consider the record with a specific id to be resolved even though a list of records from /wp/v2/books was loaded earlier on. Instead, a resolver is triggered, and an explicit GET request is issued to /wp/v2/books/1

This PR proposes resolving all per-entity resolvers after receiving the list of records.

How has this been tested?

  1. Go to the new widgets editor
  2. Make any change and click save
  3. Confirm there is no burst of GET requests following the save

Types of changes

Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@adamziel adamziel requested a review from nerrad as a code owner October 29, 2020 16:16
@adamziel adamziel self-assigned this Oct 29, 2020
@adamziel adamziel added [Package] Core data /packages/core-data [Package] Data /packages/data labels Oct 29, 2020
@github-actions
Copy link

github-actions bot commented Oct 29, 2020

Size Change: +511 B (0%)

Total Size: 1.21 MB

Filename Size Change
build/block-editor/index.js 130 kB +186 B (0%)
build/block-editor/style-rtl.css 11.1 kB +2 B (0%)
build/block-editor/style.css 11.1 kB +1 B
build/block-library/editor-rtl.css 8.97 kB -5 B (0%)
build/block-library/editor.css 8.97 kB -6 B (0%)
build/block-library/index.js 146 kB -15 B (0%)
build/block-library/style-rtl.css 7.86 kB +26 B (0%)
build/block-library/style.css 7.86 kB +23 B (0%)
build/components/index.js 172 kB +30 B (0%)
build/components/style-rtl.css 15.2 kB +2 B (0%)
build/components/style.css 15.2 kB +3 B (0%)
build/compose/index.js 9.81 kB -1 B
build/core-data/index.js 12.5 kB +206 B (1%)
build/data/index.js 8.77 kB -2 B (0%)
build/edit-navigation/index.js 11.2 kB -2 B (0%)
build/edit-post/index.js 306 kB +16 B (0%)
build/edit-post/style-rtl.css 6.41 kB +22 B (0%)
build/edit-post/style.css 6.39 kB +22 B (0%)
build/edit-site/index.js 22.1 kB -49 B (0%)
build/edit-site/style-rtl.css 3.88 kB +22 B (0%)
build/edit-site/style.css 3.88 kB +22 B (0%)
build/edit-widgets/index.js 26.4 kB -1 B
build/edit-widgets/style-rtl.css 3.13 kB +23 B (0%)
build/edit-widgets/style.css 3.13 kB +21 B (0%)
build/editor/index.js 43.1 kB -35 B (0%)
build/element/index.js 4.65 kB -1 B
build/list-reusable-blocks/index.js 3.11 kB +1 B
build/media-utils/index.js 5.34 kB +1 B
build/nux/index.js 3.42 kB +1 B
build/rich-text/index.js 13.2 kB -1 B
build/server-side-render/index.js 2.77 kB -1 B
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.78 kB 0 B
build/api-fetch/index.js 3.45 kB 0 B
build/autop/index.js 2.84 kB 0 B
build/blob/index.js 665 B 0 B
build/block-directory/index.js 8.72 kB 0 B
build/block-directory/style-rtl.css 943 B 0 B
build/block-directory/style.css 942 B 0 B
build/block-library/theme-rtl.css 837 B 0 B
build/block-library/theme.css 838 B 0 B
build/block-serialization-default-parser/index.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/blocks/index.js 48.1 kB 0 B
build/data-controls/index.js 772 B 0 B
build/date/index.js 31.8 kB 0 B
build/deprecated/index.js 768 B 0 B
build/dom-ready/index.js 571 B 0 B
build/dom/index.js 4.46 kB 0 B
build/edit-navigation/style-rtl.css 881 B 0 B
build/edit-navigation/style.css 885 B 0 B
build/editor/editor-styles-rtl.css 480 B 0 B
build/editor/editor-styles.css 482 B 0 B
build/editor/style-rtl.css 3.85 kB 0 B
build/editor/style.css 3.85 kB 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/index.js 7.7 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 2.13 kB 0 B
build/html-entities/index.js 623 B 0 B
build/i18n/index.js 3.57 kB 0 B
build/is-shallow-equal/index.js 712 B 0 B
build/keyboard-shortcuts/index.js 2.52 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/notices/index.js 1.79 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/plugins/index.js 2.56 kB 0 B
build/primitives/index.js 1.43 kB 0 B
build/priority-queue/index.js 791 B 0 B
build/redux-routine/index.js 2.85 kB 0 B
build/reusable-blocks/index.js 3.06 kB 0 B
build/shortcode/index.js 1.69 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/url/index.js 4.06 kB 0 B
build/viewport/index.js 1.84 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

@@ -173,6 +173,13 @@ export function* getEntityRecords( kind, name, query = {} ) {
}

yield receiveEntityRecords( kind, name, records, query );
for ( const record of records ) {
yield {
type: 'FINISH_RESOLUTION',
Copy link
Contributor

Choose a reason for hiding this comment

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

These are meant to be low-level actions triggered by the framework itself, not sure we should be doing this here. Can we instead bail early in getEntityRecord if the record is available?

Copy link
Contributor Author

@adamziel adamziel Nov 2, 2020

Choose a reason for hiding this comment

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

@youknowriad this was my first hunch too, but then I realized that short-circuiting when the record is available will make it impossible to invalidate that record. The resolver will simply keep returning the cached value.

Copy link
Contributor

@youknowriad youknowriad Nov 2, 2020

Choose a reason for hiding this comment

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

how is that wrong or any different from the solution here?

Copy link
Contributor Author

@adamziel adamziel Nov 2, 2020

Choose a reason for hiding this comment

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

The more I think about it, the more I believe that receiveEntityRecords should somehow mark the records as resolved conditional on invalidateCache == false? This proposed change is somehow indirect. It works because we don't have many places where records are received, but we'd have to repeat it each time we do receiveEntityRecords. Conceptually, receiving a record means it no longer needs to be resolved, right? Maybe the resolvers part of the equation could somehow listen to RECEIVE_ITEMS?

Copy link
Contributor

Choose a reason for hiding this comment

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

If you shortcircuit like I suggested above, the resolver will get called once, the bail early happens and the resolution is marked as "true" as well because the resolver ends. And we'd do so without any new API or low-level action. What's wrong with that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, you're right. I think we can try it in that case; I don't like the usage of low-level things not in the way they were meant to be used initially but it seems like the only way for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

That said, I think the current fix is not 100% accurate, it should only happen if we fetched all the fields (no _fields in the query)

Copy link
Contributor Author

@adamziel adamziel Nov 2, 2020

Choose a reason for hiding this comment

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

Good point! Hm but then if we use a limited set of fields in both getEntityRecords() and getEntityRecord(), it would still make sense to return that partial record. Which means the resolution is not just an entity-level concept but also/instead a field-level concept. That smells like a large refactor. Let's take a note and for now stick to the easy option of checking if there's no _fields in the query.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fortunately _fields is only about a subset of fields according to https://developer.wordpress.org/rest-api/using-the-rest-api/global-parameters/#_fields . It would get even more interesting if it would be possible to request additional fields that are not present by default.

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 created an issue here #26629

@adamziel
Copy link
Contributor Author

adamziel commented Nov 2, 2020

@youknowriad I added the check you suggested as well as another action, unit and integration tests, and some comments. I explored using a middleware, but I don't think we support middleware of one store dispatching actions on another store. This is as good as it gets for now.

@youknowriad
Copy link
Contributor

Why do we need the "start" action?

@adamziel
Copy link
Contributor Author

adamziel commented Nov 3, 2020

@youknowriad I think it could be safely removed. I added it purely for consistency so that we don’t have any „finish” action without a corresponding „start” action. Maybe it would prevent folks from noticing that behavior in devtools and „debugging”.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Core data /packages/core-data [Package] Data /packages/data
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants