-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Discover] Refactor app state functionality to getDiscoverAppStateContainer #149389
[Discover] Refactor app state functionality to getDiscoverAppStateContainer #149389
Conversation
@elasticmachine merge upstream |
@elasticmachine merge upstream |
Pinging @elastic/kibana-data-discovery (Team:DataDiscovery) |
@elasticmachine merge upstream |
@elasticmachine merge upstream |
…e' into discover-state-refactor-app-state
@elasticmachine merge upstream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments and suggestions, but overall lots of good refactoring here. Didn't get a chance to test locally but will continue my review tomorrow.
src/plugins/discover/public/application/main/services/discover_app_state_container.ts
Outdated
Show resolved
Hide resolved
src/plugins/discover/public/application/main/services/discover_app_state_container.ts
Outdated
Show resolved
Hide resolved
); | ||
return { fallback: !nextDataViewData.stateValFound, dataView: nextDataView }; | ||
}; | ||
|
||
return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point I think it would make sense to get rid of some of these methods that seem to just call the equivalent methods on appStateContainer
since we expose appState
directly anyway. For example, I'm not sure methods like resetInitialAppState
and getPreviousAppState
are necessary, and the duplication might just cause confusion. It might also solve the circular import issue between discover_app_state_container
and discover_state
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this should happen soon, nice cleanup potential for sure!
start(); | ||
return stop; | ||
}, | ||
setAppState: (newPartial: AppState) => setState(appStateContainerModified, newPartial), | ||
setAppState: (newPartial: AppState) => setState(appStateContainer, newPartial), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what situations would we want to call setAppState
instead of appStateContainer.update
? They seem to do the same thing except appStateContainer.update
also sets the previous state. Related to the comment above, but I feel like this could get confusing, and just calling appStateContainer.update
would probably be preferred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, another potential cleanup, I would target this when moving more functions away from the main state container
src/plugins/discover/public/application/main/services/discover_app_state_container.ts
Outdated
Show resolved
Hide resolved
@elasticmachine merge upstream |
const prevState = stateContainer.appState.getPrevious(); | ||
if (isEqualState(prevState, nextState)) { | ||
addLog('[appstate] subscribe update ignored due to no changes'); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI @mattkime this could help likely fix troubles with too much loading state triggers
FYI @davismcphee I've been adding this after you last review, it was part of the POC and would have been migrated next up, but it already makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finished local testing and a final round of code review, and everything seems to be working from what I can tell! 🎉
I left a couple suggestions that should help cleanup some imports and remove a circular dependency, but I'm also fine if we make those changes in a followup PR if preferred.
Unfortunately I did notice a significant performance degradation when switching data views, although it's not clear to me why this is happening. It seems the time it takes to switch has gone from ~150-200ms to ~500-750ms and is fairly noticeable as a user. See the videos below for examples with logging.
Before:
fast.mov
After:
slow.mov
With that said, since this isn't going in before FF and we have the whole minor to figure it out, I'm fine with merging this as is and fixing the performance issue in a followup PR if you'd prefer, so I'll approve and leave it up to you. Overall there's lots of great changes here and it definitely helps clean up Discover's state management.
@@ -165,7 +150,7 @@ export interface DiscoverStateContainer { | |||
}; | |||
} | |||
|
|||
const APP_STATE_URL_KEY = '_a'; | |||
export const APP_STATE_URL_KEY = '_a'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I left a comment on this in my last review, but I can't find it anywhere, so maybe I'm just imagining things 😅. It seems like this is only used in discover_app_state_container
and nowhere else, so it might make sense to move it there instead of exporting from here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure thing! done
import { DiscoverServices } from '../../../build_services'; | ||
import { handleSourceColumnState } from '../../../utils/state_helpers'; | ||
import { cleanupUrlState } from '../utils/cleanup_url_state'; | ||
import { getValidFilters } from '../../../utils/get_valid_filters'; | ||
|
||
export interface AppStateUrl extends Omit<AppState, 'sort'> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like AppStateUrl
also isn't used in discover_state
, and it might make sense to move it to discover_app_state_container
instead. If we moved AppStateUrl
and APP_STATE_URL_KEY
to discover_app_state_container
, it would have no imports left from discover_state
and would fix the circular dependency between discover_app_state_container
and discover_state
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point! thx! done!
Well having a whole minor of bad performance dreams 😄 ... let's have a closer look at it, my basic first testing doesn't give bad results, so I'm interested how exactly you did measure? thx |
Makes sense 😄. I tested by updating I updated /**
* Function triggered when user changes data view in the sidebar
*/
const onChangeDataView = useCallback(
async (id: string) => {
console.time('onChangeDataView');
await changeDataView(id, { services, discoverState: stateContainer, setUrlTracking });
setExpandedDoc(undefined);
},
[services, setExpandedDoc, setUrlTracking, stateContainer]
); And updated the effect that watches the data view like this: /**
* Trigger data fetching on dataView or savedSearch changes
*/
useEffect(() => {
if (dataView && initialFetchStatus === FetchStatus.LOADING) {
console.timeEnd("onChangeDataView");
refetch$.next(undefined);
}
}, [initialFetchStatus, refetch$, dataView, savedSearch.id]); In my testing it seems to be consistently slow across browsers (Chrome, Edge, Firefox, and Safari). |
@elasticmachine merge upstream |
stateContainer.dataState.reset(); | ||
stateContainer.actions.setDataView(nextDataView); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davismcphee good performance catch! I've exchanged the order of resetting the data state and the setting of the next data view. and so the performance is like before, it was one of the changes I've suggested to ease the pain of #149294 , and it seems the re-rendering it triggered caused the performance issue (when you had just a single row, it didn't matter, but with many rows, et voila!, bad)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💚 Build Succeeded
Metrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsasync chunk count
ESLint disabled line counts
References to deprecated APIs
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @kertal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pulled and tested locally again, and no more performance issue 🙌 Thanks for looking into that, LGTM!
Summary
Migrating more code changes from #140765.
discover_state.ts
todiscover_app_state_container.ts
use_discover_state.ts
to separate files adding testswindow.ELASTIC_DISCOVER_LOGGER=true
in the browser's console, logging messages by (addLog
) are displayed in the console like this:Testing
Nothing should change, nothing should break
Checklist