Skip to content

Commit

Permalink
ui: show recent executions even wihtout lock information
Browse files Browse the repository at this point in the history
Previously, if the call to retrieve contention/lock
information returned a max size limit error, we were not displaying
any data on the recent executions.
Now we show the data returned with a warning that cluster locks
information might be missing.

Part Of #96184

Release note (ui change): Still show active execution information
when there is a max size limit error.
  • Loading branch information
maryliag committed Feb 25, 2023
1 parent e7c2286 commit efdf5aa
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 27 deletions.
21 changes: 17 additions & 4 deletions pkg/ui/workspaces/cluster-ui/src/api/clusterLocksApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import {
LONG_TIMEOUT,
SqlExecutionRequest,
sqlResultsAreEmpty,
LARGE_RESULT_SIZE,
SqlApiResponse,
formatApiResult,
} from "./sqlApi";

export type ClusterLockState = {
Expand Down Expand Up @@ -48,7 +51,9 @@ type ClusterLockColumns = {
* getClusterLocksState returns information from crdb_internal.cluster_locks
* regarding the state of range locks in the cluster.
*/
export function getClusterLocksState(): Promise<ClusterLocksResponse> {
export function getClusterLocksState(): Promise<
SqlApiResponse<ClusterLocksResponse>
> {
const request: SqlExecutionRequest = {
statements: [
{
Expand All @@ -71,12 +76,16 @@ WHERE
],
execute: true,
timeout: LONG_TIMEOUT,
max_result_size: LARGE_RESULT_SIZE,
};

return executeInternalSql<ClusterLockColumns>(request).then(result => {
if (sqlResultsAreEmpty(result)) {
// No data.
return [];
return formatApiResult(
[],
result.error,
"retrieving cluster locks information",
);
}

const locks: Record<string, ClusterLockState> = {};
Expand Down Expand Up @@ -117,6 +126,10 @@ WHERE
}
});

return Object.values(locks);
return formatApiResult(
Object.values(locks),
result.error,
"retrieving luster locks information",
);
});
}
24 changes: 13 additions & 11 deletions pkg/ui/workspaces/cluster-ui/src/api/contentionApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import {
executeInternalSql,
LARGE_RESULT_SIZE,
LONG_TIMEOUT,
sqlApiErrorMessage,
SqlApiResponse,
SqlExecutionRequest,
sqlResultsAreEmpty,
formatApiResult,
} from "./sqlApi";
import { ContentionDetails } from "src/insights";
import moment from "moment";
Expand Down Expand Up @@ -44,7 +45,7 @@ export type ContentionResponseColumns = {

export async function getContentionDetailsApi(
filters?: ContentionFilters,
): Promise<ContentionDetails[]> {
): Promise<SqlApiResponse<ContentionDetails[]>> {
const request: SqlExecutionRequest = {
statements: [
{
Expand All @@ -57,16 +58,13 @@ export async function getContentionDetailsApi(
};

const result = await executeInternalSql<ContentionResponseColumns>(request);
if (result.error) {
throw new Error(
`Error while retrieving insights information: ${sqlApiErrorMessage(
result.error.message,
)}`,
);
}

if (sqlResultsAreEmpty(result)) {
return [];
return formatApiResult(
[],
result.error,
"retrieving contention information",
);
}

const contentionDetails: ContentionDetails[] = [];
Expand Down Expand Up @@ -96,7 +94,11 @@ export async function getContentionDetailsApi(
});
});

return contentionDetails;
return formatApiResult(
contentionDetails,
result.error,
"retrieving insights information",
);
}

function isFiltered(filters: ContentionFilters): boolean {
Expand Down
4 changes: 3 additions & 1 deletion pkg/ui/workspaces/cluster-ui/src/api/stmtInsightsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,14 @@ async function addStmtContentionInfoApi(
continue;
}

event.contentionEvents = await getContentionDetailsApi({
const contentionResults = await getContentionDetailsApi({
waitingTxnID: null,
waitingStmtID: event.statementExecutionID,
start: null,
end: null,
});

event.contentionEvents = contentionResults.results;
}
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,13 @@ export async function getTxnInsightsContentionDetailsApi(

// Get contention results for requested transaction.

const contentionResults = await getContentionDetailsApi({
const contentionResponse = await getContentionDetailsApi({
waitingTxnID: req.txnExecutionID,
waitingStmtID: null,
start: null,
end: null,
});
const contentionResults = contentionResponse.results;

if (contentionResults.length === 0) {
return;
Expand Down
2 changes: 1 addition & 1 deletion pkg/ui/workspaces/cluster-ui/src/queryFilter/filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export function getFullFiltersAsStringRecord(
filterKey in partialFilters &&
partialFilters[filterKey] !== inactiveFiltersState[filterKey]
) {
filters[filterKey] = partialFilters[filterKey].toString();
filters[filterKey] = partialFilters[filterKey]?.toString();
return;
}
filters[filterKey] = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ import {
const selectSessions = (state: AppState) => state.adminUI.sessions?.data;

const selectClusterLocks = (state: AppState) =>
state.adminUI.clusterLocks?.data;
state.adminUI.clusterLocks?.data?.results;

export const selectClusterLocksMaxApiSizeReached = (state: AppState) =>
!!state.adminUI.clusterLocks?.data?.maxSizeReached;

export const selectRecentExecutions = createSelector(
selectSessions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
selectRecentStatements,
selectAppName,
selectExecutionStatus,
selectClusterLocksMaxApiSizeReached,
} from "src/selectors/recentExecutions.selectors";
import { actions as localStorageActions } from "src/store/localStorage";
import { actions as sessionsActions } from "src/store/sessions";
Expand Down Expand Up @@ -58,6 +59,7 @@ export const mapStateToRecentStatementsPageProps = (
executionStatus: selectExecutionStatus(),
internalAppNamePrefix: selectAppName(state),
isTenant: selectIsTenant(state),
maxSizeApiReached: selectClusterLocksMaxApiSizeReached(state),
});

export const mapDispatchToRecentStatementsPageProps = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ import {
calculateActiveFilters,
defaultFilters,
getFullFiltersAsStringRecord,
} from "../queryFilter/filter";
} from "../queryFilter";
import { RecentStatementsSection } from "../recentExecutions/recentStatementsSection";
import { queryByName, syncHistory } from "src/util/query";
import { getTableSortFromURL } from "../sortedtable/getTableSortFromURL";
import { getRecentStatementFiltersFromURL } from "src/queryFilter/utils";
import { Pagination } from "src/pagination";
import { InlineAlert } from "@cockroachlabs/ui-components";

import styles from "./statementsPage.module.scss";

Expand All @@ -58,6 +59,7 @@ export type RecentStatementsViewStateProps = {
executionStatus: string[];
internalAppNamePrefix: string;
isTenant?: boolean;
maxSizeApiReached?: boolean;
};

export type RecentStatementsViewProps = RecentStatementsViewStateProps &
Expand All @@ -76,6 +78,7 @@ export const RecentStatementsView: React.FC<RecentStatementsViewProps> = ({
executionStatus,
internalAppNamePrefix,
isTenant,
maxSizeApiReached,
}: RecentStatementsViewProps) => {
const [pagination, setPagination] = useState<ISortedTablePagination>({
current: 1,
Expand Down Expand Up @@ -231,6 +234,17 @@ export const RecentStatementsView: React.FC<RecentStatementsViewProps> = ({
total={filteredStatements?.length}
onChange={onChangePage}
/>
{maxSizeApiReached && (
<InlineAlert
intent="info"
title={
<>
Not all contention events are displayed because the maximum
number of contention events was reached in the console.
</>
}
/>
)}
</Loading>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { DOMAIN_NAME, noopReducer } from "../utils";
import { ClusterLocksResponse } from "src/api";
import { ClusterLocksResponse, SqlApiResponse } from "src/api";

export type ClusterLocksReqState = {
data: ClusterLocksResponse;
data: SqlApiResponse<ClusterLocksResponse>;
lastError: Error;
valid: boolean;
};
Expand All @@ -28,7 +28,10 @@ const clusterLocksSlice = createSlice({
name: `${DOMAIN_NAME}/clusterLocks`,
initialState,
reducers: {
received: (state, action: PayloadAction<ClusterLocksResponse>) => {
received: (
state,
action: PayloadAction<SqlApiResponse<ClusterLocksResponse>>,
) => {
state.data = action.payload;
state.valid = true;
state.lastError = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
selectAppName,
selectRecentTransactions,
selectExecutionStatus,
selectClusterLocksMaxApiSizeReached,
} from "src/selectors/recentExecutions.selectors";
import { actions as localStorageActions } from "src/store/localStorage";
import { actions as sessionsActions } from "src/store/sessions";
Expand Down Expand Up @@ -58,6 +59,7 @@ export const mapStateToRecentTransactionsPageProps = (
executionStatus: selectExecutionStatus(),
internalAppNamePrefix: selectAppName(state),
isTenant: selectIsTenant(state),
maxSizeApiReached: selectClusterLocksMaxApiSizeReached(state),
});

export const mapDispatchToRecentTransactionsPageProps = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import {
calculateActiveFilters,
Filter,
getFullFiltersAsStringRecord,
} from "../queryFilter/filter";
inactiveFiltersState,
} from "../queryFilter";
import { getAppsFromRecentExecutions } from "../recentExecutions/recentStatementUtils";
import { inactiveFiltersState } from "../queryFilter/filter";
import { RecentTransactionsSection } from "src/recentExecutions/recentTransactionsSection";
import { Pagination } from "src/pagination";

Expand All @@ -39,6 +39,7 @@ import { queryByName, syncHistory } from "src/util/query";
import { getTableSortFromURL } from "src/sortedtable/getTableSortFromURL";
import { getRecentTransactionFiltersFromURL } from "src/queryFilter/utils";
import { filterRecentTransactions } from "../recentExecutions/recentStatementUtils";
import { InlineAlert } from "@cockroachlabs/ui-components";
const cx = classNames.bind(styles);

export type RecentTransactionsViewDispatchProps = {
Expand All @@ -57,6 +58,7 @@ export type RecentTransactionsViewStateProps = {
sortSetting: SortSetting;
internalAppNamePrefix: string;
isTenant?: boolean;
maxSizeApiReached?: boolean;
};

export type RecentTransactionsViewProps = RecentTransactionsViewStateProps &
Expand All @@ -78,6 +80,7 @@ export const RecentTransactionsView: React.FC<RecentTransactionsViewProps> = ({
filters,
executionStatus,
internalAppNamePrefix,
maxSizeApiReached,
}: RecentTransactionsViewProps) => {
const [pagination, setPagination] = useState<ISortedTablePagination>({
current: 1,
Expand Down Expand Up @@ -234,6 +237,17 @@ export const RecentTransactionsView: React.FC<RecentTransactionsViewProps> = ({
total={filteredTransactions?.length}
onChange={onChangePage}
/>
{maxSizeApiReached && (
<InlineAlert
intent="info"
title={
<>
Not all contention events are displayed because the maximum
number of contention events was reached in the console.
</>
}
/>
)}
</Loading>
</div>
</div>
Expand Down
4 changes: 3 additions & 1 deletion pkg/ui/workspaces/db-console/src/redux/apiReducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,9 @@ export interface APIReducersState {
statementDiagnosticsReports: CachedDataReducerState<clusterUiApi.StatementDiagnosticsResponse>;
userSQLRoles: CachedDataReducerState<api.UserSQLRolesResponseMessage>;
hotRanges: PaginatedCachedDataReducerState<api.HotRangesV2ResponseMessage>;
clusterLocks: CachedDataReducerState<clusterUiApi.ClusterLocksResponse>;
clusterLocks: CachedDataReducerState<
clusterUiApi.SqlApiResponse<clusterUiApi.ClusterLocksResponse>
>;
stmtInsights: CachedDataReducerState<
clusterUiApi.SqlApiResponse<StmtInsightEvent[]>
>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ import { SessionsResponseMessage } from "src/util/api";
const selectSessions = (state: AdminUIState) => state.cachedData.sessions?.data;

const selectClusterLocks = (state: AdminUIState) =>
state.cachedData.clusterLocks?.data;
state.cachedData.clusterLocks?.data?.results;

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

export const selectRecentExecutions = createSelector(
selectSessions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
selectRecentStatements,
selectAppName,
selectExecutionStatus,
selectClusterLocksMaxApiSizeReached,
} from "src/selectors";
import { refreshLiveWorkload } from "src/redux/apiReducers";
import { LocalSetting } from "src/redux/localsettings";
Expand Down Expand Up @@ -59,6 +60,7 @@ export const mapStateToRecentStatementViewProps = (state: AdminUIState) => ({
executionStatus: selectExecutionStatus(),
sessionsError: state.cachedData?.sessions.lastError,
internalAppNamePrefix: selectAppName(state),
maxSizeApiReached: selectClusterLocksMaxApiSizeReached(state),
});

export const recentStatementsViewActions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
selectAppName,
selectRecentTransactions,
selectExecutionStatus,
selectClusterLocksMaxApiSizeReached,
} from "src/selectors";
import { refreshLiveWorkload } from "src/redux/apiReducers";
import { LocalSetting } from "src/redux/localsettings";
Expand Down Expand Up @@ -60,6 +61,7 @@ export const mapStateToRecentTransactionsPageProps = (state: AdminUIState) => ({
executionStatus: selectExecutionStatus(),
sortSetting: sortSettingLocalSetting.selector(state),
internalAppNamePrefix: selectAppName(state),
maxSizeApiReached: selectClusterLocksMaxApiSizeReached(state),
});

// This object is just for convenience so we don't need to supply dispatch to
Expand Down

0 comments on commit efdf5aa

Please sign in to comment.