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

[Fiber] "Task" priority for error boundaries and batched updates #8193

Merged
merged 11 commits into from
Nov 4, 2016

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Nov 3, 2016

Introduces a new priority level, Task. (The name is provisional. We'll come up with something better later.)

Task priority is similar to Synchronous priority. Both are flushed in the current tick. The difference is

  • work with the Task priority is performed within the current tick, but at the end of the batch of work (after all work has been committed).
  • work with the Synchronous priority is performed immediately. E.g. a synchronous setState will perform all its work before the setState call exits.

In #8127, these two types of work priority were both considered "synchronous." Splitting them into separate concepts will make it easier to schedule and batch things correctly.

Currently used for batchedUpdates and nested sync updates. Task should also be used for updates inside componentDidUpdate/Mount, error boundary work, and events. I'll leave these for a future PR.

There's an error boundary regression that I haven't looked at yet. I'll investigate it in the morning. Pushing this now because I'm about to go to bed and I don't want to block @gaearon.

There was lots of duplication across all the scheduling functions. I
think we're far enough along that we can start trying to clean some
stuff up.

Also introduces a new priority level provisionally called Task priority.
This is for work that completes at the end of the current tick, after
the current batch of work has been committed. It's different from
Synchronous priority, which needs to complete immediately.

A full implementation of Task priority will follow. It will replace
the current batching solution.
Task priority is similar to Synchronous priority. Both are flushed in
the current tick. Synchronous priority is flushed immediately (e.g. sync
work triggered by setState will flush before setState exits), where as
Task is flushed after the current batch of work is committed.

Currently used for batchedUpdates and nested sync updates. Task should
also be used for componentDidUpdate/Mount and error boundary work. I'll
add this in a later commit.
I have all but one error fixed. Not sure how tricky the last one is,
but I'm cautiously optimistic. Pushing to show my current progress.
@acdlite
Copy link
Collaborator Author

acdlite commented Nov 4, 2016

Pushed a new commit that passes all the error boundary tests. Changed the algorithm of handleErrors a bit to ensure that boundaries are not revisited once they are acknowledged, which prevents the same boundary from being visited over and over again. I had to move the functions in ReactFiberErrorBoundary.js into the scheduler so they have access to its state.

This passes all the error boundary tests and the incremental tests; however, it's causing an infinite loop in one of the files when I try to run the full suite. Haven't figured out which one yet. Unfortunately, the infinite loop means I can't run the record-tests script to see which tests might be failing. Working on Fiber is like whack-a-mole sometimes :D

I feel pretty good about the overall approach here, though. Will continue to investigate which test is breaking tonight; if I can't find it, I'll pick it up in the morning.

@gaearon

@acdlite
Copy link
Collaborator Author

acdlite commented Nov 4, 2016

Found it! The test is should only call componentWillUnmount once in ReactCompositeComponent-test.js. Makes sense.

@acdlite
Copy link
Collaborator Author

acdlite commented Nov 4, 2016

Yay! I got it working!

Could use a bit more cleanup, but this should be ready for review @gaearon.

if (maybeErrorBoundary.tag === ClassComponent) {
const instance = maybeErrorBoundary.stateNode;
if (typeof instance.unstable_handleError === 'function' &&
!knownBoundaries.has(maybeErrorBoundary)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This line here is how I got it to work, and why I had to move this function into the scheduler.

@acdlite acdlite force-pushed the fibertaskpriority branch 2 times, most recently from 6ddb725 to c3cad3b Compare November 4, 2016 07:47
Changed the algorithm of handleErrors a bit to ensure that boundaries
are not revisited once they are acknowledged.
Discovered an edge case: a noop error boundary will break in incremental
mode unless you explicitly schedule an update.
@acdlite acdlite changed the title [Fiber] Initial implementation of "Task" priority [Fiber] "Task Nov 4, 2016
@acdlite acdlite changed the title [Fiber] "Task [Fiber] "Task" priority for error boundaries and batched updates Nov 4, 2016
gaearon and others added 4 commits November 4, 2016 18:23
[Fiber] Refactor error boundaries in Fiber
The existing logic was written before we had a proper error handling system.
Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

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

Accepting if you kill the remaining recursion.

@@ -13,7 +13,7 @@

var ReactDOMFeatureFlags = {
useCreateElement: true,
useFiber: false,
useFiber: true,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Careful

Copy link
Collaborator

Choose a reason for hiding this comment

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

Unless you consider it ready for 15.4.0 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hehe :D

@gaearon gaearon merged commit 4266f08 into facebook:master Nov 4, 2016
@gaearon
Copy link
Collaborator

gaearon commented Nov 4, 2016

@gaearon gaearon mentioned this pull request Nov 8, 2016
4 tasks
acusti pushed a commit to brandcast/react that referenced this pull request Mar 15, 2017
…ebook#8193)

* Refactor scheduling functions and introduce Task priority

There was lots of duplication across all the scheduling functions. I
think we're far enough along that we can start trying to clean some
stuff up.

Also introduces a new priority level provisionally called Task priority.
This is for work that completes at the end of the current tick, after
the current batch of work has been committed. It's different from
Synchronous priority, which needs to complete immediately.

A full implementation of Task priority will follow. It will replace
the current batching solution.

* Implement Task priority

Task priority is similar to Synchronous priority. Both are flushed in
the current tick. Synchronous priority is flushed immediately (e.g. sync
work triggered by setState will flush before setState exits), where as
Task is flushed after the current batch of work is committed.

Currently used for batchedUpdates and nested sync updates. Task should
also be used for componentDidUpdate/Mount and error boundary work. I'll
add this in a later commit.

* Make error boundaries use Task Priority

I have all but one error fixed. Not sure how tricky the last one is,
but I'm cautiously optimistic. Pushing to show my current progress.

* Remove recursion from handleErrors

Changed the algorithm of handleErrors a bit to ensure that boundaries
are not revisited once they are acknowledged.

* Add incremental error boundary test

Discovered an edge case: a noop error boundary will break in incremental
mode unless you explicitly schedule an update.

* Refactor error boundaries in Fiber

* Simplify trapError() calls

The existing logic was written before we had a proper error handling system.

* Remove unnecessary flags

* Prevent performTaskWork recursion

* Be stricter about preventing recursion
Copy link

@koobino1 koobino1 left a comment

Choose a reason for hiding this comment

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

Leave a Comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants