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

[BUGFIX beta] Avoid rerendering outlet state during router destruction. #14123

Merged
merged 1 commit into from
Aug 24, 2016

Conversation

rwjblue
Copy link
Member

@rwjblue rwjblue commented Aug 24, 2016

During each Ember.Route's willDestroy we trigger a run.once(this.router, '_setOutlets');. This is so that the routes views are destroyed properly (by removing them from the outlet state).

During Ember.Router's willDestroy we clear this._toplevelView (along with a bunch of other cleanup).

These two things combined can mean that this._toplevelView is null when _setOutlets is called again (during the Router's destruction). In that scenario we are actually creating another this._toplevelView and setting up another rendered root (since one doesn't exist). When this happens the newly created root is never cleaned up, since the Router's willDestroy has already ran and can no longer clean up after itself.


This fixes a number of test failures that crop up when doing fuzz testing (via seed URL param with QUnit).

@stefanpenner
Copy link
Member

stefanpenner commented Aug 24, 2016

@rwjblue this may be tricky, but can we test this? Testing some observable "We did rerender" would help prevent regressions in this future.

@rwjblue
Copy link
Member Author

rwjblue commented Aug 24, 2016

@stefanpenner - I don't know. This was the result of a gnarly debugging session when running Ember's own tests in randomized order (where there were a large number of failures since leaking a root view in Glimmer is worse).

I am happy to try to add a specific test, but I think the only way to do it would be to force the router to be destroyed before a route instance.

During each `Ember.Route`'s `willDestroy` we trigger a
`run.once(this.router, '_setOutlets');`. This is so that the routes
views are destroyed properly (by removing them from the outlet state).

During `Ember.Router`'s `willDestroy` we clear
`this._toplevelView` (along with a bunch of other cleanup).

These two things combined can mean that `this._toplevelView` is `null`
when `_setOutlets` is called again (during the `Router`'s destruction).
In that scenario we are actually creating another
`this._toplevelView` and setting up another rendered root (since one
doesn't exist). When this happens the newly created root is never
cleaned up, since the Router's `willDestroy` has already ran and can no
longer clean up after itself.
@rwjblue rwjblue force-pushed the fix-router-teardown branch from c3a4dac to 890fb04 Compare August 24, 2016 16:15
@rwjblue
Copy link
Member Author

rwjblue commented Aug 24, 2016

@stefanpenner - Added two tests (one with an engine and one without). Tests fail before this change.

@stefanpenner
Copy link
Member

tests look legit

@rwjblue rwjblue merged commit ffde338 into emberjs:master Aug 24, 2016
@rwjblue rwjblue deleted the fix-router-teardown branch August 24, 2016 19:09
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.

2 participants