feat: Synchronously return cached charts (#15157)

* feat: Synchronously return cached charts

* Fix lint issue

* Fix python lint error

* Change getChartDataRequest to return response

* Fix lint errors

* Add test

* explore_json: skip cached data check for forced refresh

Co-authored-by: Rob DiCiuccio <rob.diciuccio@gmail.com>
This commit is contained in:
Ben Reinhart
2021-06-22 10:00:57 -07:00
committed by GitHub
parent 4d48f0426d
commit ab153e66cc
8 changed files with 181 additions and 83 deletions

View File

@@ -145,11 +145,12 @@ const legacyChartDataRequest = async (
'GET' && isFeatureEnabled(FeatureFlag.CLIENT_CACHE)
? SupersetClient.get
: SupersetClient.post;
return clientMethod(querySettings).then(({ json }) =>
return clientMethod(querySettings).then(({ json, response }) =>
// Make the legacy endpoint return a payload that corresponds to the
// V1 chart data endpoint response signature.
({
result: [json],
response,
json: { result: [json] },
}),
);
};
@@ -196,7 +197,8 @@ const v1ChartDataRequest = async (
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
};
return SupersetClient.post(querySettings).then(({ json }) => json);
return SupersetClient.post(querySettings);
};
export async function getChartDataRequest({
@@ -390,14 +392,25 @@ export function exploreJSON(
dispatch(chartUpdateStarted(controller, formData, key));
const chartDataRequestCaught = chartDataRequest
.then(response => {
const queriesResponse = response.result;
.then(({ response, json }) => {
if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) {
// deal with getChartDataRequest transforming the response data
const result = 'result' in response ? response.result[0] : response;
return waitForAsyncData(result);
const result = 'result' in json ? json.result[0] : json;
switch (response.status) {
case 200:
// Query results returned synchronously, meaning query was already cached.
return Promise.resolve([result]);
case 202:
// Query is running asynchronously and we must await the results
return waitForAsyncData(result);
default:
throw new Error(
`Received unexpected response status (${response.status}) while fetching chart data`,
);
}
}
return queriesResponse;
return json.result;
})
.then(queriesResponse => {
queriesResponse.forEach(resultItem =>
@@ -541,11 +554,11 @@ export function postChartFormData(
export function redirectSQLLab(formData) {
return dispatch => {
getChartDataRequest({ formData, resultFormat: 'json', resultType: 'query' })
.then(({ result }) => {
.then(({ json }) => {
const redirectUrl = '/superset/sqllab/';
const payload = {
datasourceKey: formData.datasource,
sql: result[0].query,
sql: json.result[0].query,
};
postForm(redirectUrl, payload);
})

View File

@@ -118,25 +118,36 @@ const FilterValue: React.FC<FilterProps> = ({
requestParams: { dashboardId: 0 },
ownState: filterOwnState,
})
.then(response => {
.then(({ response, json }) => {
if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) {
// deal with getChartDataRequest transforming the response data
const result = 'result' in response ? response.result[0] : response;
waitForAsyncData(result)
.then((asyncResult: ChartDataResponseResult[]) => {
setIsRefreshing(false);
setIsLoading(false);
setState(asyncResult);
})
.catch((error: ClientErrorObject) => {
setError(
error.message || error.error || t('Check configuration'),
);
setIsRefreshing(false);
setIsLoading(false);
});
const result = 'result' in json ? json.result[0] : json;
if (response.status === 200) {
setIsRefreshing(false);
setIsLoading(false);
setState([result]);
} else if (response.status === 202) {
waitForAsyncData(result)
.then((asyncResult: ChartDataResponseResult[]) => {
setIsRefreshing(false);
setIsLoading(false);
setState(asyncResult);
})
.catch((error: ClientErrorObject) => {
setError(
error.message || error.error || t('Check configuration'),
);
setIsRefreshing(false);
setIsLoading(false);
});
} else {
throw new Error(
`Received unexpected response status (${response.status}) while fetching chart data`,
);
}
} else {
setState(response.result);
setState(json.result);
setError('');
setIsRefreshing(false);
setIsLoading(false);

View File

@@ -421,24 +421,35 @@ const FiltersConfigForm = (
force,
requestParams: { dashboardId: 0 },
})
.then(response => {
.then(({ response, json }) => {
if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) {
// deal with getChartDataRequest transforming the response data
const result = 'result' in response ? response.result[0] : response;
waitForAsyncData(result)
.then((asyncResult: ChartDataResponseResult[]) => {
setNativeFilterFieldValuesWrapper({
defaultValueQueriesData: asyncResult,
});
})
.catch((error: ClientErrorObject) => {
setError(
error.message || error.error || t('Check configuration'),
);
const result = 'result' in json ? json.result[0] : json;
if (response.status === 200) {
setNativeFilterFieldValuesWrapper({
defaultValueQueriesData: [result],
});
} else if (response.status === 202) {
waitForAsyncData(result)
.then((asyncResult: ChartDataResponseResult[]) => {
setNativeFilterFieldValuesWrapper({
defaultValueQueriesData: asyncResult,
});
})
.catch((error: ClientErrorObject) => {
setError(
error.message || error.error || t('Check configuration'),
);
});
} else {
throw new Error(
`Received unexpected response status (${response.status}) while fetching chart data`,
);
}
} else {
setNativeFilterFieldValuesWrapper({
defaultValueQueriesData: response.result,
defaultValueQueriesData: json.result,
});
}
})

View File

@@ -149,9 +149,9 @@ export const DataTablesPane = ({
resultType,
ownState,
})
.then(response => {
.then(({ json }) => {
// Only displaying the first query is currently supported
const result = response.result[0];
const result = json.result[0];
setData(prevData => ({ ...prevData, [resultType]: result.data }));
setIsLoading(prevIsLoading => ({
...prevIsLoading,

View File

@@ -58,9 +58,9 @@ const ViewQueryModal: React.FC<Props> = props => {
resultFormat: 'json',
resultType,
})
.then(response => {
.then(({ json }) => {
// Only displaying the first query is currently supported
const result = response.result[0];
const result = json.result[0];
setLanguage(result.language);
setQuery(result.query);
setIsLoading(false);