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

feat(sqllab): non-blocking persistence mode #24539

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
297 changes: 53 additions & 244 deletions superset-frontend/src/SqlLab/actions/sqlLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export const CREATE_DATASOURCE_STARTED = 'CREATE_DATASOURCE_STARTED';
export const CREATE_DATASOURCE_SUCCESS = 'CREATE_DATASOURCE_SUCCESS';
export const CREATE_DATASOURCE_FAILED = 'CREATE_DATASOURCE_FAILED';

export const SET_EDITOR_TAB_LAST_UPDATE = 'SET_EDITOR_TAB_LAST_UPDATE';

export const addInfoToast = addInfoToastAction;
export const addSuccessToast = addSuccessToastAction;
export const addDangerToast = addDangerToastAction;
Expand Down Expand Up @@ -160,6 +162,10 @@ export function updateQueryEditor(alterations) {
return { type: UPDATE_QUERY_EDITOR, alterations };
}

export function setEditorTabLastUpdate(timestamp) {
return { type: SET_EDITOR_TAB_LAST_UPDATE, timestamp };
}

export function scheduleQuery(query) {
return dispatch =>
SupersetClient.post({
Expand Down Expand Up @@ -237,44 +243,11 @@ export function startQuery(query) {
}

export function querySuccess(query, results) {
return function (dispatch) {
const sqlEditorId = results?.query?.sqlEditorId;
const sync =
sqlEditorId &&
!query.isDataPreview &&
isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${sqlEditorId}`),
postPayload: { latest_query_id: query.id },
})
: Promise.resolve();

return sync
.then(() => dispatch({ type: QUERY_SUCCESS, query, results }))
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while storing the latest query id in the backend. ' +
'Please contact your administrator if this problem persists.',
),
),
),
);
};
return { type: QUERY_SUCCESS, query, results };
}

export function queryFailed(query, msg, link, errors) {
return function (dispatch) {
const sync =
!query.isDataPreview &&
isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${query.sqlEditorId}`),
postPayload: { latest_query_id: query.id },
})
: Promise.resolve();

const eventData = {
has_err: true,
start_offset: query.startDttm,
Expand All @@ -295,22 +268,7 @@ export function queryFailed(query, msg, link, errors) {
});
});

return (
sync
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while storing the latest query id in the backend. ' +
'Please contact your administrator if this problem persists.',
),
),
),
)
// We should always show the error message, even if we couldn't sync the
// state to the backend
.then(() => dispatch({ type: QUERY_FAILED, query, msg, link, errors }))
);
dispatch({ type: QUERY_FAILED, query, msg, link, errors });
};
}

Expand Down Expand Up @@ -557,14 +515,15 @@ export function addQueryEditor(queryEditor) {
? SupersetClient.post({
endpoint: '/tabstateview/',
postPayload: { queryEditor },
})
: Promise.resolve({ json: { id: shortid.generate() } });
}).then(({ json }) => ({ ...json, loaded: true }))
: Promise.resolve({ id: shortid.generate() });

return sync
.then(({ json }) => {
.then(({ id, loaded }) => {
const newQueryEditor = {
...queryEditor,
id: json.id.toString(),
id: id.toString(),
loaded,
};
return dispatch({
type: ADD_QUERY_EDITOR,
Expand Down Expand Up @@ -736,11 +695,6 @@ export function switchQueryEditor(queryEditor, displayLimit) {
schema: json.schema,
queryLimit: json.query_limit,
remoteId: json.saved_query?.id,
validationResult: {
id: null,
errors: [],
completed: false,
},
hideLeftBar: json.hide_left_bar,
};
dispatch(loadQueryEditor(loadedQueryEditor));
Expand Down Expand Up @@ -770,31 +724,10 @@ export function setActiveSouthPaneTab(tabId) {

export function toggleLeftBar(queryEditor) {
const hideLeftBar = !queryEditor.hideLeftBar;
return function (dispatch) {
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { hide_left_bar: hideLeftBar },
})
: Promise.resolve();

return sync
.then(() =>
dispatch({
type: QUERY_EDITOR_TOGGLE_LEFT_BAR,
queryEditor,
hideLeftBar,
}),
)
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while hiding the left bar. Please contact your administrator.',
),
),
),
);
return {
type: QUERY_EDITOR_TOGGLE_LEFT_BAR,
queryEditor,
hideLeftBar,
};
}

Expand Down Expand Up @@ -856,110 +789,26 @@ export function removeQuery(query) {
}

export function queryEditorSetDb(queryEditor, dbId) {
return function (dispatch) {
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { database_id: dbId },
})
: Promise.resolve();

return sync
.then(() => dispatch({ type: QUERY_EDITOR_SETDB, queryEditor, dbId }))
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while setting the tab database ID. Please contact your administrator.',
),
),
),
);
};
return { type: QUERY_EDITOR_SETDB, queryEditor, dbId };
}

export function queryEditorSetSchema(queryEditor, schema) {
return function (dispatch) {
const sync =
isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE) &&
typeof queryEditor === 'object'
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { schema },
})
: Promise.resolve();

return sync
.then(() =>
dispatch({
type: QUERY_EDITOR_SET_SCHEMA,
queryEditor: queryEditor || {},
schema,
}),
)
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while setting the tab schema. Please contact your administrator.',
),
),
),
);
return {
type: QUERY_EDITOR_SET_SCHEMA,
queryEditor: queryEditor || {},
schema,
};
}

export function queryEditorSetAutorun(queryEditor, autorun) {
return function (dispatch) {
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { autorun },
})
: Promise.resolve();

return sync
.then(() =>
dispatch({ type: QUERY_EDITOR_SET_AUTORUN, queryEditor, autorun }),
)
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while setting the tab autorun. Please contact your administrator.',
),
),
),
);
};
return { type: QUERY_EDITOR_SET_AUTORUN, queryEditor, autorun };
}

export function queryEditorSetTitle(queryEditor, name, id) {
return function (dispatch) {
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${id}`),
postPayload: { label: name },
})
: Promise.resolve();

return sync
.then(() =>
dispatch({
type: QUERY_EDITOR_SET_TITLE,
queryEditor: { ...queryEditor, id },
name,
}),
)
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while setting the tab name. Please contact your administrator.',
),
),
),
);
return {
type: QUERY_EDITOR_SET_TITLE,
queryEditor: { ...queryEditor, id },
name,
};
}

Expand Down Expand Up @@ -1029,32 +878,19 @@ export function updateSavedQuery(query, clientId) {
.then(() => dispatch(updateQueryEditor(query)));
}

export function queryEditorSetSql(queryEditor, sql) {
return { type: QUERY_EDITOR_SET_SQL, queryEditor, sql };
export function queryEditorSetSql(queryEditor, sql, queryId) {
return { type: QUERY_EDITOR_SET_SQL, queryEditor, sql, queryId };
}

export function formatQuery(queryEditor) {
return function (dispatch, getState) {
const { sql } = getUpToDateQuery(getState(), queryEditor);
return SupersetClient.post({
endpoint: `/api/v1/sqllab/format_sql/`,
body: JSON.stringify({ sql }),
headers: { 'Content-Type': 'application/json' },
}).then(({ json }) => {
dispatch(queryEditorSetSql(queryEditor, json.result));
});
};
}

export function queryEditorSetAndSaveSql(targetQueryEditor, sql) {
export function queryEditorSetAndSaveSql(targetQueryEditor, sql, queryId) {
return function (dispatch, getState) {
const queryEditor = getUpToDateQuery(getState(), targetQueryEditor);
// saved query and set tab state use this action
dispatch(queryEditorSetSql(queryEditor, sql));
dispatch(queryEditorSetSql(queryEditor, sql, queryId));
if (isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)) {
return SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { sql, latest_query_id: queryEditor.latestQueryId },
postPayload: { sql, latest_query_id: queryId },
}).catch(() =>
dispatch(
addDangerToast(
Expand All @@ -1071,59 +907,32 @@ export function queryEditorSetAndSaveSql(targetQueryEditor, sql) {
};
}

export function queryEditorSetQueryLimit(queryEditor, queryLimit) {
return function (dispatch) {
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { query_limit: queryLimit },
})
: Promise.resolve();
export function formatQuery(queryEditor) {
return function (dispatch, getState) {
const { sql } = getUpToDateQuery(getState(), queryEditor);
return SupersetClient.post({
endpoint: `/api/v1/sqllab/format_sql/`,
body: JSON.stringify({ sql }),
headers: { 'Content-Type': 'application/json' },
}).then(({ json }) => {
dispatch(queryEditorSetSql(queryEditor, json.result));
});
};
}

return sync
.then(() =>
dispatch({
type: QUERY_EDITOR_SET_QUERY_LIMIT,
queryEditor,
queryLimit,
}),
)
.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while setting the tab name. Please contact your administrator.',
),
),
),
);
export function queryEditorSetQueryLimit(queryEditor, queryLimit) {
return {
type: QUERY_EDITOR_SET_QUERY_LIMIT,
queryEditor,
queryLimit,
};
}

export function queryEditorSetTemplateParams(queryEditor, templateParams) {
return function (dispatch) {
dispatch({
type: QUERY_EDITOR_SET_TEMPLATE_PARAMS,
queryEditor,
templateParams,
});
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
? SupersetClient.put({
endpoint: encodeURI(`/tabstateview/${queryEditor.id}`),
postPayload: { template_params: templateParams },
})
: Promise.resolve();

return sync.catch(() =>
dispatch(
addDangerToast(
t(
'An error occurred while setting the tab template parameters. ' +
'Please contact your administrator.',
),
),
),
);
return {
michael-s-molina marked this conversation as resolved.
Show resolved Hide resolved
type: QUERY_EDITOR_SET_TEMPLATE_PARAMS,
queryEditor,
templateParams,
};
}

Expand Down
Loading
Loading