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] Remove output field #8406

Merged
merged 2 commits into from
Nov 24, 2016
Merged

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Nov 24, 2016

The idea was originally that each fiber has a return value. In practice most of what we're modeling here are void functions and we track side effects instead of return values.

We do use this for coroutines to short cut access to terminal yields. However, since this can be nested fragments we end up searching the tree anyway. We also have to manage this in transferOutput so it ends up being as expensive. Maybe we can save some traversal for updates when coroutine branches bail out but meh.

Swapped the .child and .stateNode on coroutines so that .stateNode is the first phase and .child is the completed phase. This is a bit more useful.

Unmount nodes from the first phase when the parent is unmounted.

nextChildren,
priorityLevel
);
} else if (current.child === workInProgress.child) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this be current.stateNode === workInProgress.stateNode?
I changed it, and tests still pass.
Is this unobservable, or are we missing a test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We no coverage of time slicing or bailouts for coroutines at all yet.


transferDeletions(workInProgress);
}
// markChildAsProgressed(current, workInProgress, priorityLevel);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I get that we can't do this now because there is no equivalent of the progressedChild for the stateNode. Does this affect correctness, or does it just mean coroutines aren't as capable of reusing work? Is this comment actionable or can it be removed?

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 is a bit of a WIP still. It might be correctness related. I'm not even sure.

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.

Coroutines are still confusing to me but they're broken anyway (#8413). Killing output looks good.

@@ -296,7 +296,41 @@ module.exports = function<T, P, I, TI, C>(
if (!coroutine) {
throw new Error('Should be resolved by now');
}
reconcileChildren(current, workInProgress, coroutine.children);

const nextChildren = coroutine.children;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd appreciate a comment here mentioning that this code is pretty much the same as reconcileChildren(), but operating on stateNode.

@@ -288,7 +288,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {

const returnFiber = workInProgress.return;

if (returnFiber) {
if (returnFiber && !next) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does it hang without this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because the first time the coroutine completes, it adds itself to the effect list. Then it does its child, and completes again.

Not sure what happens if there are no children in the first phase. It probably breaks anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, it's because the new test uses classes which have "update effects" scheduled on them to invoke the life-cycles. Those effects gets scheduled twice.

@sebmarkbage
Copy link
Collaborator Author

I'll land just the first two commits.

The idea was originally that each fiber has a return value. In practice
most of what we're modelling here are void functions and we track side
effects instead of return values.

We do use this for coroutines to short cut access to terminal yields.
However, since this can be nested fragments we end up searching the tree
anyway. We also have to manage this in transferOutput so it ends up being
as expensive. Maybe we can save some traversal for updates when coroutine
branches bail out but meh.
@sebmarkbage sebmarkbage merged commit 0ba8434 into facebook:master Nov 24, 2016
koba04 added a commit to koba04/react-fiber-architecture that referenced this pull request Nov 29, 2016
`output` filed has been removed.
facebook/react#8406
acusti pushed a commit to brandcast/react that referenced this pull request Mar 15, 2017
* Remove output field

The idea was originally that each fiber has a return value. In practice
most of what we're modelling here are void functions and we track side
effects instead of return values.

We do use this for coroutines to short cut access to terminal yields.
However, since this can be nested fragments we end up searching the tree
anyway. We also have to manage this in transferOutput so it ends up being
as expensive. Maybe we can save some traversal for updates when coroutine
branches bail out but meh.

* Unmount child from the first phase of a coroutine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants