Skip to content

Commit

Permalink
ui: show data when max size reached
Browse files Browse the repository at this point in the history
Previously, when the sql api returned a max size reached
error, we were just showing the error, but not the data
that was also being returned.

This PR creates a new function to format the return of
the api calls, so when is a max size error it doesn't
throw an error, but still pass that info so we can display
a warning on the pages.

This commit updates the Insights Workload > Statement page
with the new behaviour.
Following PRs will update other usages of the sql api.

Part Of: cockroachdb#96184
Release note (ui change): Still show data on the console
(with a warning) for Statement Insights when we reach a
"max size exceed" error from the sql api.
  • Loading branch information
maryliag committed Feb 22, 2023
1 parent df0c962 commit 88415f2
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 5 deletions.
30 changes: 30 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/api/sqlApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ export type SqlExecutionErrorMessage = {
source: { file: string; line: number; function: "string" };
};

export type ApiResponse<ResultType> = {
maxSizeReached: boolean;
results: Array<ResultType>;
};

export const SQL_API_PATH = "/api/v2/sql/";

/**
Expand Down Expand Up @@ -141,3 +146,28 @@ export function sqlApiErrorMessage(message: string): string {
}
return message;
}

function isMaxSizeError(message: string): boolean {
return !!message?.includes("max result size exceeded");
}

export function formatApiResult(
results: Array<any>,
error: SqlExecutionErrorMessage,
errorMessageContext: string,
): ApiResponse<any> {
const maxSizeError = isMaxSizeError(error?.message);

if (error && !maxSizeError) {
throw new Error(
`Error while ${errorMessageContext}: ${sqlApiErrorMessage(
error?.message,
)}`,
);
}

return {
maxSizeReached: maxSizeError,
results: results,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ import sortableTableStyles from "src/sortedtable/sortedtable.module.scss";
import ColumnsSelector from "../../../columnsSelector/columnsSelector";
import { SelectOption } from "../../../multiSelectCheckbox/multiSelectCheckbox";
import { TimeScale } from "../../../timeScaleDropdown";
import { InlineAlert } from "@cockroachlabs/ui-components";
import { insights } from "src/util";
import { Anchor } from "src/anchor";

const cx = classNames.bind(styles);
const sortableTableCx = classNames.bind(sortableTableStyles);
Expand All @@ -58,6 +61,7 @@ export type StatementInsightsViewStateProps = {
selectedColumnNames: string[];
dropDownSelect?: React.ReactElement;
isTenant?: boolean;
maxSizeApiReached?: boolean;
};

export type StatementInsightsViewDispatchProps = {
Expand Down Expand Up @@ -90,6 +94,7 @@ export const StatementInsightsView: React.FC<StatementInsightsViewProps> = (
selectedColumnNames,
dropDownSelect,
isTenant,
maxSizeApiReached,
} = props;

const [pagination, setPagination] = useState<ISortedTablePagination>({
Expand Down Expand Up @@ -283,6 +288,20 @@ export const StatementInsightsView: React.FC<StatementInsightsViewProps> = (
total={statementInsights?.length}
onChange={onChangePage}
/>
{maxSizeApiReached && (
<InlineAlert
intent="info"
title={
<>
Not all insights are displayed because the maximum number of
insights was reached in the console.&nbsp;
<Anchor href={insights} target="_blank">
Learn more
</Anchor>
</>
}
/>
)}
</div>
</Loading>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
selectColumns,
selectStatementInsights,
selectStatementInsightsError,
selectStmtInsightsMaxApiReached,
} from "src/store/insights/statementInsights";
import {
actions as transactionInsights,
Expand Down Expand Up @@ -65,6 +66,7 @@ const statementMapStateToProps = (
sortSetting: selectSortSetting(state),
selectedColumnNames: selectColumns(state),
isTenant: selectIsTenant(state),
maxSizeApiReached: selectStmtInsightsMaxApiReached(state),
});

const TransactionDispatchProps = (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2023 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

import { createSelector } from "reselect";
import { AppState } from "src/store/reducers";

import { selectStatementFingerprintID } from "src/selectors/common";

export const selectStatementFingerprintInsights = createSelector(
(state: AppState) => state.adminUI?.statementFingerprintInsights?.cachedData,
selectStatementFingerprintID,
(cachedFingerprintInsights, fingerprintID) => {
if (!cachedFingerprintInsights) {
return null;
}
return cachedFingerprintInsights[fingerprintID]?.data?.results;
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { DOMAIN_NAME, noopReducer } from "../../utils";
import moment, { Moment } from "moment";
import { StatementInsights } from "src/api/insightsApi";
import { ApiResponse } from "src/api";

export type StatementInsightsState = {
data: StatementInsights;
data: ApiResponse<StatementInsights>;
lastUpdated: Moment;
lastError: Error;
valid: boolean;
Expand All @@ -31,7 +32,7 @@ const statementInsightsSlice = createSlice({
name: `${DOMAIN_NAME}/statementInsightsSlice`,
initialState,
reducers: {
received: (state, action: PayloadAction<StatementInsights>) => {
received: (state, action: PayloadAction<ApiResponse<StatementInsights>>) => {
state.data = action.payload;
state.valid = true;
state.lastError = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ import {
} from "src/selectors/insightsCommon.selectors";
import { selectID } from "src/selectors/common";
export const selectStatementInsights = createSelector(
(state: AppState) => state.adminUI.statementInsights?.data,
(state: AppState) => state.adminUI.statementInsights?.data?.results,
selectStatementInsightsCombiner,
);

export const selectStatementInsightsError = (state: AppState) =>
state.adminUI.statementInsights?.lastError;

export const selectStmtInsightsMaxApiReached = (state: AppState): boolean =>
state.adminUI.statementInsights?.data?.maxSizeReached;

export const selectStatementInsightDetails = createSelector(
selectStatementInsights,
selectID,
Expand Down
2 changes: 1 addition & 1 deletion pkg/ui/workspaces/db-console/src/redux/apiReducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ export interface APIReducersState {
clusterLocks: CachedDataReducerState<clusterUiApi.ClusterLocksResponse>;
transactionInsights: CachedDataReducerState<clusterUiApi.TransactionInsightEventsResponse>;
transactionInsightDetails: KeyedCachedDataReducerState<clusterUiApi.TransactionInsightEventDetailsResponse>;
statementInsights: CachedDataReducerState<clusterUiApi.StatementInsights>;
statementInsights: CachedDataReducerState<clusterUiApi.ApiResponse<clusterUiApi.StatementInsights>>;
schemaInsights: CachedDataReducerState<clusterUiApi.InsightRecommendation[]>;
schedules: KeyedCachedDataReducerState<clusterUiApi.Schedules>;
schedule: KeyedCachedDataReducerState<clusterUiApi.Schedule>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ export const selectTransactionInsightDetails = createSelector(
},
);

export const selectStmtInsightsMaxApiReached = (
state: AdminUIState,
): boolean => {
return !!state.cachedData.statementInsights?.data?.maxSizeReached;
};

export const selectTransactionInsightDetailsError = createSelector(
(state: AdminUIState) => state.cachedData.transactionInsightDetails,
selectID,
Expand All @@ -69,7 +75,7 @@ export const selectTransactionInsightDetailsError = createSelector(
);

export const selectStatementInsights = createSelector(
(state: AdminUIState) => state.cachedData.statementInsights?.data,
(state: AdminUIState) => state.cachedData.statementInsights?.data?.results,
selectStatementInsightsCombiner,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
selectStatementInsights,
sortSettingLocalSetting,
selectTransactionInsights,
selectStmtInsightsMaxApiReached,
} from "src/views/insights/insightsSelectors";
import { bindActionCreators } from "redux";
import { LocalSetting } from "src/redux/localsettings";
Expand Down Expand Up @@ -64,6 +65,7 @@ const statementMapStateToProps = (
sortSetting: sortSettingLocalSetting.selector(state),
selectedColumnNames:
insightStatementColumnsLocalSetting.selectorToArray(state),
maxSizeApiReached: selectStmtInsightsMaxApiReached(state),
});

const TransactionDispatchProps = {
Expand Down

0 comments on commit 88415f2

Please sign in to comment.