Skip to content

Commit

Permalink
[8.x] [Discover] Enhance Discover loading time by parallel execution …
Browse files Browse the repository at this point in the history
…of requests (#195670) (#195939)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Discover] Enhance Discover loading time by parallel execution of
requests (#195670)](#195670)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Matthias
Wilhelm","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-11T14:47:50Z","message":"[Discover]
Enhance Discover loading time by parallel execution of requests
(#195670)\n\nIn the loading process of Discover, there were 4 sequential
requests. This commit refactors the code to execute them in a parallel
way. Before theduration of requests were adding up, now it takes as long
as the longest\r\nrequest. This can speed up the loading Discover
significantly, depending on how long those requests
take.\r\n\r\nCo-authored-by: Julia Rechkunova
<[email protected]>","sha":"dc1aced57d238324b48496e64c5fb8a5a9e9dcd3","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Discover","performance","release_note:skip","v9.0.0","Team:DataDiscovery","backport:prev-minor","Project:OneDiscover"],"title":"[Discover]
Enhance Discover loading time by parallel execution of
requests","number":195670,"url":"https://github.com/elastic/kibana/pull/195670","mergeCommit":{"message":"[Discover]
Enhance Discover loading time by parallel execution of requests
(#195670)\n\nIn the loading process of Discover, there were 4 sequential
requests. This commit refactors the code to execute them in a parallel
way. Before theduration of requests were adding up, now it takes as long
as the longest\r\nrequest. This can speed up the loading Discover
significantly, depending on how long those requests
take.\r\n\r\nCo-authored-by: Julia Rechkunova
<[email protected]>","sha":"dc1aced57d238324b48496e64c5fb8a5a9e9dcd3"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/195670","number":195670,"mergeCommit":{"message":"[Discover]
Enhance Discover loading time by parallel execution of requests
(#195670)\n\nIn the loading process of Discover, there were 4 sequential
requests. This commit refactors the code to execute them in a parallel
way. Before theduration of requests were adding up, now it takes as long
as the longest\r\nrequest. This can speed up the loading Discover
significantly, depending on how long those requests
take.\r\n\r\nCo-authored-by: Julia Rechkunova
<[email protected]>","sha":"dc1aced57d238324b48496e64c5fb8a5a9e9dcd3"}}]}]
BACKPORT-->

Co-authored-by: Matthias Wilhelm <[email protected]>
  • Loading branch information
kibanamachine and kertal authored Oct 11, 2024
1 parent 81bd359 commit ba70b83
Showing 1 changed file with 58 additions and 53 deletions.
111 changes: 58 additions & 53 deletions src/plugins/discover/public/application/main/discover_main_route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ export function DiscoverMainRoute({
});
const [error, setError] = useState<Error>();
const [loading, setLoading] = useState(true);
const [hasESData, setHasESData] = useState(false);
const [hasUserDataView, setHasUserDataView] = useState(false);
const [showNoDataPage, setShowNoDataPage] = useState<boolean>(false);
const [noDataState, setNoDataState] = useState({
hasESData: false,
hasUserDataView: false,
showNoDataPage: false,
});
const hasCustomBranding = useObservable(core.customBranding.hasCustomBranding$, false);

/**
Expand All @@ -109,46 +111,49 @@ export function DiscoverMainRoute({
page: 'app',
id: savedSearchId || 'new',
});
/**
* Helper function to determine when to skip the no data page
*/
const skipNoDataPage = useCallback(
async (nextDataView?: DataView) => {
try {
const { dataSource } = stateContainer.appState.getState();
const isEsqlQuery = isDataSourceType(dataSource, DataSourceType.Esql);

const checkData = useCallback(async () => {
try {
if (savedSearchId) {
return true; // bypass NoData screen
}

if (isDataSourceType(stateContainer.appState.getState().dataSource, DataSourceType.Esql)) {
return true;
}

const hasUserDataViewValue = await data.dataViews.hasData
.hasUserDataView()
.catch(() => false);
const hasESDataValue = await data.dataViews.hasData.hasESData().catch(() => false);
setHasUserDataView(hasUserDataViewValue);
setHasESData(hasESDataValue);
// ES|QL should work without data views
// Given we have a saved search id, we can skip the data/data view check, too
// A given nextDataView is provided by the user, and therefore we can skip the data/data view check

if (!hasUserDataViewValue) {
setShowNoDataPage(true);
return false;
}
if (savedSearchId || isEsqlQuery || nextDataView) {
if (!isEsqlQuery) {
await stateContainer.actions.loadDataViewList();
}
return true;
}

let defaultDataViewExists: boolean = false;
try {
defaultDataViewExists = await data.dataViews.defaultDataViewExists();
const [hasUserDataViewValue, hasESDataValue, defaultDataViewExists] = await Promise.all([
data.dataViews.hasData.hasUserDataView().catch(() => false),
data.dataViews.hasData.hasESData().catch(() => false),
data.dataViews.defaultDataViewExists().catch(() => false),
stateContainer.actions.loadDataViewList(),
]);

if (!hasUserDataViewValue || !defaultDataViewExists) {
setNoDataState({
showNoDataPage: true,
hasESData: hasESDataValue,
hasUserDataView: hasUserDataViewValue,
});
return false;
}
return true;
} catch (e) {
//
}

if (!defaultDataViewExists) {
setShowNoDataPage(true);
setError(e);
return false;
}
return true;
} catch (e) {
setError(e);
return false;
}
}, [data.dataViews, savedSearchId, stateContainer.appState]);
},
[data.dataViews, savedSearchId, stateContainer]
);

const loadSavedSearch = useCallback(
async ({
Expand All @@ -157,13 +162,12 @@ export function DiscoverMainRoute({
}: { nextDataView?: DataView; initialAppState?: LoadParams['initialAppState'] } = {}) => {
const loadSavedSearchStartTime = window.performance.now();
setLoading(true);
if (!nextDataView && !(await checkData())) {
const skipNoData = await skipNoDataPage(nextDataView);
if (!skipNoData) {
setLoading(false);
return;
}
try {
await stateContainer.actions.loadDataViewList();

const currentSavedSearch = await stateContainer.actions.loadSavedSearch({
savedSearchId,
dataView: nextDataView,
Expand Down Expand Up @@ -214,8 +218,8 @@ export function DiscoverMainRoute({
}
},
[
checkData,
stateContainer.actions,
skipNoDataPage,
stateContainer,
savedSearchId,
historyLocationState?.dataViewSpec,
customizationContext.displayMode,
Expand All @@ -231,11 +235,12 @@ export function DiscoverMainRoute({

useEffect(() => {
if (!isCustomizationServiceInitialized) return;

setLoading(true);
setHasESData(false);
setHasUserDataView(false);
setShowNoDataPage(false);
setNoDataState({
hasESData: false,
hasUserDataView: false,
showNoDataPage: false,
});
setError(undefined);
if (savedSearchId) {
loadSavedSearch();
Expand All @@ -259,7 +264,7 @@ export function DiscoverMainRoute({
async (nextDataView: unknown) => {
if (nextDataView) {
setLoading(true);
setShowNoDataPage(false);
setNoDataState((state) => ({ ...state, showNoDataPage: false }));
setError(undefined);
await loadSavedSearch({ nextDataView: nextDataView as DataView });
}
Expand All @@ -281,15 +286,15 @@ export function DiscoverMainRoute({

// We've already called this, so we can optimize the analytics services to
// use the already-retrieved data to avoid a double-call.
hasESData: () => Promise.resolve(hasESData),
hasUserDataView: () => Promise.resolve(hasUserDataView),
hasESData: () => Promise.resolve(noDataState.hasESData),
hasUserDataView: () => Promise.resolve(noDataState.hasUserDataView),
},
},
share,
dataViewEditor,
noDataPage: services.noDataPage,
}),
[core, data.dataViews, dataViewEditor, hasESData, hasUserDataView, services.noDataPage, share]
[core, data.dataViews, dataViewEditor, noDataState, services.noDataPage, share]
);

const loadingIndicator = useMemo(
Expand All @@ -298,7 +303,7 @@ export function DiscoverMainRoute({
);

const mainContent = useMemo(() => {
if (showNoDataPage) {
if (noDataState.showNoDataPage) {
const importPromise = import('@kbn/shared-ux-page-analytics-no-data');
const AnalyticsNoDataPageKibanaProvider = withSuspense(
React.lazy(() =>
Expand Down Expand Up @@ -336,7 +341,7 @@ export function DiscoverMainRoute({
noDataDependencies,
onDataViewCreated,
onESQLNavigationComplete,
showNoDataPage,
noDataState.showNoDataPage,
stateContainer,
]);

Expand All @@ -357,7 +362,7 @@ export function DiscoverMainRoute({
<>
<DiscoverTopNavInline
stateContainer={stateContainer}
hideNavMenuItems={loading || showNoDataPage}
hideNavMenuItems={loading || noDataState.showNoDataPage}
/>
{mainContent}
</>
Expand Down

0 comments on commit ba70b83

Please sign in to comment.