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

Refactor saveEntityRecord from redux-rungen to async thunks #33201

Merged
merged 14 commits into from
Aug 30, 2021

Conversation

adamziel
Copy link
Contributor

@adamziel adamziel commented Jul 5, 2021

Builds on top of the thunks support added in #27276 and refactors just the parts of core-data required to make the saveEntityRecord work (this PR is a minimal viable subset of #28389).

Test plan:

So you ask how to test this PR? The impact surface is pretty big. For sure confirm all the tests are green – that is a good indicator of the overall health. You may want to play with the Gutenberg too:

  • Create a new post and save it, confirm the preview works
  • Add a blog title block, edit it, save the post and related entities
  • Play the widgets editor, add new widgets, update the existing ones
  • Anything else that comes to your mind

@adamziel adamziel requested a review from nerrad as a code owner July 5, 2021 14:14
@github-actions
Copy link

github-actions bot commented Jul 5, 2021

Size Change: +105 B (0%)

Total Size: 1.04 MB

Filename Size Change
build/core-data/index.min.js 12.5 kB +105 B (+1%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 931 B
build/admin-manifest/index.min.js 1.09 kB
build/annotations/index.min.js 2.7 kB
build/api-fetch/index.min.js 2.19 kB
build/autop/index.min.js 2.08 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.2 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/index.min.js 119 kB
build/block-editor/style-rtl.css 13.8 kB
build/block-editor/style.css 13.8 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 474 B
build/block-library/blocks/button/editor.css 474 B
build/block-library/blocks/button/style-rtl.css 605 B
build/block-library/blocks/button/style.css 604 B
build/block-library/blocks/buttons/editor-rtl.css 315 B
build/block-library/blocks/buttons/editor.css 315 B
build/block-library/blocks/buttons/style-rtl.css 370 B
build/block-library/blocks/buttons/style.css 370 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 194 B
build/block-library/blocks/columns/editor.css 193 B
build/block-library/blocks/columns/style-rtl.css 474 B
build/block-library/blocks/columns/style.css 475 B
build/block-library/blocks/cover/editor-rtl.css 666 B
build/block-library/blocks/cover/editor.css 670 B
build/block-library/blocks/cover/style-rtl.css 1.23 kB
build/block-library/blocks/cover/style.css 1.23 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 400 B
build/block-library/blocks/embed/style.css 400 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 879 B
build/block-library/blocks/gallery/editor.css 876 B
build/block-library/blocks/gallery/style-rtl.css 1.7 kB
build/block-library/blocks/gallery/style.css 1.7 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 70 B
build/block-library/blocks/group/theme.css 70 B
build/block-library/blocks/heading/editor-rtl.css 113 B
build/block-library/blocks/heading/editor.css 113 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 B
build/block-library/blocks/html/editor-rtl.css 283 B
build/block-library/blocks/html/editor.css 284 B
build/block-library/blocks/image/editor-rtl.css 728 B
build/block-library/blocks/image/editor.css 728 B
build/block-library/blocks/image/style-rtl.css 482 B
build/block-library/blocks/image/style.css 487 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 63 B
build/block-library/blocks/list/style.css 63 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 488 B
build/block-library/blocks/media-text/style.css 485 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 473 B
build/block-library/blocks/navigation-link/editor.css 473 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation/editor-rtl.css 1.7 kB
build/block-library/blocks/navigation/editor.css 1.71 kB
build/block-library/blocks/navigation/style-rtl.css 1.44 kB
build/block-library/blocks/navigation/style.css 1.44 kB
build/block-library/blocks/navigation/view.min.js 2.52 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 310 B
build/block-library/blocks/page-list/editor.css 310 B
build/block-library/blocks/page-list/style-rtl.css 241 B
build/block-library/blocks/page-list/style.css 241 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 248 B
build/block-library/blocks/paragraph/style.css 248 B
build/block-library/blocks/post-author/editor-rtl.css 210 B
build/block-library/blocks/post-author/editor.css 210 B
build/block-library/blocks/post-author/style-rtl.css 182 B
build/block-library/blocks/post-author/style.css 181 B
build/block-library/blocks/post-comments-form/style-rtl.css 140 B
build/block-library/blocks/post-comments-form/style.css 140 B
build/block-library/blocks/post-comments/style-rtl.css 360 B
build/block-library/blocks/post-comments/style.css 359 B
build/block-library/blocks/post-content/editor-rtl.css 138 B
build/block-library/blocks/post-content/editor.css 138 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 398 B
build/block-library/blocks/post-featured-image/editor.css 398 B
build/block-library/blocks/post-featured-image/style-rtl.css 143 B
build/block-library/blocks/post-featured-image/style.css 143 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 378 B
build/block-library/blocks/post-template/style.css 379 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 60 B
build/block-library/blocks/post-title/style.css 60 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 361 B
build/block-library/blocks/pullquote/style.css 360 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B
build/block-library/blocks/query-pagination/editor.css 262 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B
build/block-library/blocks/query-pagination/style.css 168 B
build/block-library/blocks/query-title/editor-rtl.css 85 B
build/block-library/blocks/query-title/editor.css 85 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 169 B
build/block-library/blocks/quote/style.css 169 B
build/block-library/blocks/quote/theme-rtl.css 220 B
build/block-library/blocks/quote/theme.css 222 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 374 B
build/block-library/blocks/search/style.css 375 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 250 B
build/block-library/blocks/separator/style.css 250 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 462 B
build/block-library/blocks/site-logo/editor.css 464 B
build/block-library/blocks/site-logo/style-rtl.css 153 B
build/block-library/blocks/site-logo/style.css 153 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 165 B
build/block-library/blocks/social-link/editor.css 165 B
build/block-library/blocks/social-links/editor-rtl.css 812 B
build/block-library/blocks/social-links/editor.css 811 B
build/block-library/blocks/social-links/style-rtl.css 1.33 kB
build/block-library/blocks/social-links/style.css 1.33 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 636 B
build/block-library/blocks/template-part/editor.css 635 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/editor-rtl.css 90 B
build/block-library/blocks/term-description/editor.css 90 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 1.29 kB
build/block-library/common.css 1.29 kB
build/block-library/editor-rtl.css 9.94 kB
build/block-library/editor.css 9.92 kB
build/block-library/index.min.js 150 kB
build/block-library/reset-rtl.css 527 B
build/block-library/reset.css 527 B
build/block-library/style-rtl.css 10.7 kB
build/block-library/style.css 10.7 kB
build/block-library/theme-rtl.css 658 B
build/block-library/theme.css 663 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 47 kB
build/components/index.min.js 209 kB
build/components/style-rtl.css 15.8 kB
build/components/style.css 15.8 kB
build/compose/index.min.js 10.2 kB
build/customize-widgets/index.min.js 11.1 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 614 B
build/data/index.min.js 7.1 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 428 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.53 kB
build/edit-navigation/index.min.js 13.6 kB
build/edit-navigation/style-rtl.css 3.14 kB
build/edit-navigation/style.css 3.14 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 28.8 kB
build/edit-post/style-rtl.css 7.2 kB
build/edit-post/style.css 7.19 kB
build/edit-site/index.min.js 26.3 kB
build/edit-site/style-rtl.css 5.07 kB
build/edit-site/style.css 5.07 kB
build/edit-widgets/index.min.js 16 kB
build/edit-widgets/style-rtl.css 4.06 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 37.6 kB
build/editor/style-rtl.css 3.74 kB
build/editor/style.css 3.73 kB
build/element/index.min.js 3.17 kB
build/escape-html/index.min.js 517 B
build/format-library/index.min.js 5.36 kB
build/format-library/style-rtl.css 668 B
build/format-library/style.css 669 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.59 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.49 kB
build/keycodes/index.min.js 1.25 kB
build/list-reusable-blocks/index.min.js 1.85 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.88 kB
build/notices/index.min.js 845 B
build/nux/index.min.js 2.03 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.83 kB
build/primitives/index.min.js 921 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.63 kB
build/reusable-blocks/index.min.js 2.28 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.6 kB
build/server-side-render/index.min.js 1.32 kB
build/shortcode/index.min.js 1.48 kB
build/token-list/index.min.js 562 B
build/url/index.min.js 1.74 kB
build/viewport/index.min.js 1.02 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 6.27 kB
build/widgets/style-rtl.css 1.05 kB
build/widgets/style.css 1.05 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@adamziel adamziel force-pushed the thunkify/saveEntityRecord branch from 66eec97 to abc2cac Compare August 25, 2021 15:00
@adamziel adamziel changed the title Migrate saveEntityRecord to thunks Refactor saveEntityRecord from redux-rungen to async thunks Aug 25, 2021
@adamziel adamziel requested a review from jsnajdr August 25, 2021 15:49
@adamziel
Copy link
Contributor Author

The last missing part are the unit tests for saveEditedEntity that I commented out as they test a generator and not an async thunk. I will adjust that part, and in the meantime I am opening this PR for reviews – it could be a big step towards getting rid of rungen from core-data cc @jsnajdr

@noisysocks
Copy link
Member

Update the tests and 👍 lgtm. Doing this bit by bit makes sense.

@jsnajdr
Copy link
Member

jsnajdr commented Aug 26, 2021

@adamziel I have a more ambitious version of this refactoring in #28389. It migrates the entire core-data store at once.

I just successfully rebased and updated the old version from January, and currently it compiles and I'm trying to make it work.

I'm not sure yet which will be a better approach -- migrate one store at a time, or migrate individual generator functions?

If we migrate one function at a time, I'm a bit worried whether the generators and thunks, the yields and awaits, will really work together.

@adamziel
Copy link
Contributor Author

adamziel commented Aug 26, 2021

I just updated the tests, all the checks are green now!

@jsnajdr as much as I'd love to do it in one swoop, I'm afraid that such a big PR targeting a place like that could get stuck in a long discussion/rebase loop. Every time e.g. actions.js gets updated there would be a need for another rebase and conflict resolution. That's just my guess – it could go smoothly too.

If we migrate one function at a time, I'm a bit worried whether the generators and thunks, the yields and awaits, will really work together.

That was my concern too, but it looks like they play together pretty nicely – dispatch() can handle both just fine.

Copy link
Member

@jsnajdr jsnajdr left a comment

Choose a reason for hiding this comment

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

The great news is that this refactor is almost identical to my "in one swoop" version in #28389 🎉 That shows that we are on the right path and that incremental landing of this work is possible.

There's a bug in ifNotResolved that should be fixed.

Most other comments are about a fact that the thunk refactor reveals very well: some actions are synchronous, some are asynchronous and we need to await dispatches only of the asynchronous ones.

For saveEntityRecord, the two only async places are:

  • waiting for the store lock
  • issuing the fetch request

Everything else is just updating the state in memory (all the receive... actions), and releasing a lock is also sync.

With thunks, dispatch( actionThunk ) is little more than a glorified function call that injects some dependencies into that function. And it's very clear, much clearer than with generators and yields, that if the thunk function is sync, the dispatch is also sync. And dispatching an action object ({ type: ..., ... }), once there are no controls, is also always sync.

);
yield editEntityRecord(
await dispatch.editEntityRecord(
Copy link
Member

Choose a reason for hiding this comment

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

My version doesn't do await here, because editEntityRecord is a synchronous action. It merely writes things to memory (updating state) and never does any request or anything else async.

@@ -406,22 +403,20 @@ export function* saveEntityRecord(
}
}

yield {
await dispatch( {
Copy link
Member

Choose a reason for hiding this comment

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

This action is also purely synchronous.

packages/core-data/src/actions.js Outdated Show resolved Hide resolved
await dispatch.receiveAutosaves(
persistedRecord.id,
updatedRecord
);
Copy link
Member

Choose a reason for hiding this comment

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

Both receiveEntityRecords and receiveAutosaves are synchronous: they merely write the new/updated records to state.

}
yield receiveEntityRecords(
await dispatch.receiveEntityRecords(
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 sync.

@@ -566,20 +555,20 @@ export function* saveEntityRecord(
} catch ( _error ) {
error = _error;
}
yield {
dispatch( {
type: 'SAVE_ENTITY_RECORD_FINISH',
Copy link
Member

Choose a reason for hiding this comment

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

Also sync.


return updatedRecord;
} finally {
yield* __unstableReleaseStoreLock( lock );
await dispatch( __unstableReleaseStoreLock( lock ) );
Copy link
Member

Choose a reason for hiding this comment

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

Unlocking is sync.

packages/core-data/src/actions.js Outdated Show resolved Hide resolved
packages/core-data/src/actions.js Outdated Show resolved Hide resolved
packages/core-data/src/utils/if-not-resolved.js Outdated Show resolved Hide resolved
@jsnajdr
Copy link
Member

jsnajdr commented Aug 27, 2021

That was my concern too, but it looks like they play together pretty nicely – dispatch() can handle both just fine.

@adamziel I just found one limitation where yield and thunks don't work together.

In a generator, you can yield a plain action -- yield { type: 'FOO' } -- and rungen will dispatch it to the store.

Rungen will also dispatch a generator/iterator:

function* action() {
  yield a;
  yield b;
}

and

yield action();

will execute that generator.

But yielding a thunk doesn't work, because rungen doesn't have a handler for that. You need to use the dispatch control explicitly.

@adamziel
Copy link
Contributor Author

adamziel commented Aug 27, 2021

There's a bug in ifNotResolved that should be fixed.

Done done, good spot!

With thunks, dispatch( actionThunk ) is little more than a glorified function call that injects some dependencies into that function. And it's very clear, much clearer than with generators and yields, that if the thunk function is sync, the dispatch is also sync. And dispatching an action object ({ type: ..., ... }), once there are no controls, is also always sync.

I see the merit and value in that. At the same time, I see two problems:

  1. I need to decide whether the function I call is async or not. Sometimes this decision is trivial, sometimes it requires me to read quite some code (e.g. with dispatch( getKindEntities( kind ) ))
  2. If I call dispatch.someAction(); in a bunch of places and, later on, refactor someAction to be asynchronous – I just unknowingly broke a number of actions. I don't think this is detectable by a type system or a linter in an easy way which means that we'd rely solely on developers ability to get a non-obvious detail correct every single time. It would probably work most of the time, but without automated checks I also think we'd be setting ourselves up for breaking things sooner or later.

On the flipside, the only cost of defaulting to await is moving some code to the next tick. I believe that, most of the time, this is negligible. The only situation I can think of where this could maybe matter is typing. Fortunately, we have no dispatch() calls in editEntityRecord.

Either way – I propose we get this PR in with all the awaits in place, and then have this discussion in a separate issue and maybe bring more people in.

@adamziel
Copy link
Contributor Author

adamziel commented Aug 27, 2021

But yielding a thunk doesn't work, because rungen doesn't have a handler for that. You need to use the dispatch control explicitly.

@jsnajdr You're right! I think it would be possible to provide a handler as a rungen "control" (like the one it has for promises], but maybe we don't have to.

It seems like:

  • Generators can dispatch anything but thunks
  • Thunks can truly dispatch anything including other thunks

Let's just keep working through the generators that are not yielded by any other generators (so leafs in the directed dependency graph) and hope we have no cyclic dependencies. Even if we do have cyclic deps, we could have one PR for each set of them. This way with every PR our dependency graph shrinks, and eventually we'll cover all the nodes. If we run into a case we can't handle that way, let's regroup.

@jsnajdr
Copy link
Member

jsnajdr commented Aug 27, 2021

I think it would be possible to provide a handler as a "control"

Yes, it would be possible to expand the isAction check in redux-routine to detect thunks. In addition to plain objects with a string type property, it would detect and dispatch also functions.

But that could break backward compatibility. Until now,

const x = yield () => 'x';

assigned the function to x, yield was pass-through. But now it would execute that function and assign 'x' to the x variable.

As we're migrating away from redux-routine anyway, I'd rather not introduce fragile changes like this.

@adamziel adamziel force-pushed the thunkify/saveEntityRecord branch from ac3d052 to 4049925 Compare August 27, 2021 12:14
Copy link
Member

@jsnajdr jsnajdr left a comment

Choose a reason for hiding this comment

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

Looks good to me now 👍 If all tests pass, this is ready to merge.

docs/reference-guides/data/data-core.md Outdated Show resolved Hide resolved
@adamziel
Copy link
Contributor Author

adamziel commented Aug 27, 2021

The only broken test is also broken in trunk – I'll wait for the performance checks and merge this one.

Edit: I won't because e2e tests are now required :D Either someone can help me here (@gziolo ?), or this will have to wait until trunk is fixed.

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

Aren't there some comments from @jsnajdr that still could be addressed?

Another way to land this PR faster is to skip those failing tests and rebase with trunk. Otherwise, I can merge on Monday 😅

packages/core-data/src/test/actions.js Outdated Show resolved Hide resolved
@adamziel
Copy link
Contributor Author

adamziel commented Aug 27, 2021

Aren't there some comments from @jsnajdr that still could be addressed?

All the remaining ones are about await-ing and not await-ing in certain places – we are discussing that but it is not a blocker for this PR, I think we'll see a big issue thread about it at some point.

Another way to land this PR faster is to skip those failing tests and rebase with trunk. Otherwise, I can merge on Monday 😅

👍

@adamziel adamziel force-pushed the thunkify/saveEntityRecord branch from cb136b4 to 0989625 Compare August 30, 2021 10:42
@adamziel adamziel merged commit 0dc7ad2 into trunk Aug 30, 2021
@adamziel adamziel deleted the thunkify/saveEntityRecord branch August 30, 2021 11:28
@github-actions github-actions bot added this to the Gutenberg 11.5 milestone Aug 30, 2021
@getsource getsource added the [Type] Code Quality Issues or PRs that relate to code quality label Sep 8, 2021
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 [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants