Skip to content

Commit

Permalink
Merge pull request #103612 from THardy98/backport22.2-96431
Browse files Browse the repository at this point in the history
release-22.2: ui: databases shows partial results for size limit error
  • Loading branch information
Thomas Hardy authored May 19, 2023
2 parents f15f8f4 + 564d194 commit b97bfe7
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 11 deletions.
47 changes: 42 additions & 5 deletions pkg/ui/workspaces/cluster-ui/src/databasesPage/databasesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ function filterBySearchQuery(
.every(val => matchString.includes(val));
}

const tablePageSize = 20;
const disableTableSortSize = tablePageSize * 2;

export class DatabasesPage extends React.Component<
DatabasesPageProps,
DatabasesPageState
Expand All @@ -191,7 +194,7 @@ export class DatabasesPage extends React.Component<
filters: defaultFilters,
pagination: {
current: 1,
pageSize: 20,
pageSize: tablePageSize,
},
lastDetailsError: null,
};
Expand Down Expand Up @@ -295,22 +298,51 @@ export class DatabasesPage extends React.Component<
}

let lastDetailsError: Error;
this.props.databases.forEach(database => {

// load everything by default
let filteredDbs = this.props.databases;

// Loading only the first page if there are more than
// 40 dbs. If there is more than 40 dbs sort will be disabled.
if (this.props.databases.length > disableTableSortSize) {
const startIndex =
this.state.pagination.pageSize * (this.state.pagination.current - 1);
// Result maybe filtered so get db names from filtered results
if (this.props.search && this.props.search.length > 0) {
filteredDbs = this.filteredDatabasesData();
}

if (!filteredDbs || filteredDbs.length === 0) {
return;
}

// Only load the first page
filteredDbs = filteredDbs.slice(
startIndex,
startIndex + this.state.pagination.pageSize,
);
}

filteredDbs.forEach(database => {
if (database.lastError !== undefined) {
lastDetailsError = database.lastError;
}

if (
lastDetailsError &&
this.state.lastDetailsError?.name != lastDetailsError?.name
) {
this.setState({ lastDetailsError: lastDetailsError });
}

if (
!database.loaded &&
!database.loading &&
database.lastError === undefined
(database.lastError === undefined ||
database.lastError?.name === "GetDatabaseInfoError")
) {
return this.props.refreshDatabaseDetails(database.name);
this.props.refreshDatabaseDetails(database.name);
return;
}

database.missingTables.forEach(table => {
Expand Down Expand Up @@ -480,7 +512,10 @@ export class DatabasesPage extends React.Component<
database: DatabasesPageDataDatabase,
cell: React.ReactNode,
): React.ReactNode => {
if (database.lastError) {
if (
database.lastError &&
database.lastError.name !== "GetDatabaseInfoError"
) {
return "(unavailable)";
}
return cell;
Expand Down Expand Up @@ -674,6 +709,7 @@ export class DatabasesPage extends React.Component<
onChangeSortSetting={this.changeSortSetting}
pagination={this.state.pagination}
loading={this.props.loading}
disableSortSizeLimit={disableTableSortSize}
renderNoResult={
<div
className={cx(
Expand Down Expand Up @@ -708,6 +744,7 @@ export class DatabasesPage extends React.Component<
timeout: this.state.lastDetailsError?.name
?.toLowerCase()
.includes("timeout"),
error: this.state.lastDetailsError,
})
}
/>
Expand Down
15 changes: 14 additions & 1 deletion pkg/ui/workspaces/cluster-ui/src/sortedtable/sortedtable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ interface SortedTableProps<T> {
pagination?: ISortedTablePagination;
loading?: boolean;
loadingLabel?: string;
disableSortSizeLimit?: number;
// empty state for table
empty?: boolean;
emptyProps?: EmptyPanelProps;
Expand Down Expand Up @@ -225,6 +226,14 @@ export class SortedTable<T> extends React.Component<
if (!sortSetting) {
return this.paginatedData();
}

if (
this.props.disableSortSizeLimit &&
data.length > this.props.disableSortSizeLimit
) {
return this.paginatedData();
}

const sortColumn = columns.find(c => c.name === sortSetting.columnTitle);
if (!sortColumn || !sortColumn.sort) {
return this.paginatedData();
Expand Down Expand Up @@ -253,13 +262,17 @@ export class SortedTable<T> extends React.Component<
rollups: React.ReactNode[],
columns: ColumnDescriptor<T>[],
) => {
const sort =
!this.props.disableSortSizeLimit ||
this.props.data.length <= this.props.disableSortSizeLimit;

return columns.map((cd, ii): SortableColumn => {
return {
name: cd.name,
title: cd.title,
hideTitleUnderline: cd.hideTitleUnderline,
cell: index => cd.cell(sorted[index]),
columnTitle: cd.sort ? cd.name : undefined,
columnTitle: sort && cd.sort ? cd.name : undefined,
rollup: rollups[ii],
className: cd.className,
titleAlign: cd.titleAlign,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,17 @@ const cx = classNames.bind(styles);
interface SQLActivityErrorProps {
statsType: string;
timeout?: boolean;
error?: Error;
}

const LoadingError: React.FC<SQLActivityErrorProps> = props => {
if (props.error && props.error.name === "GetDatabaseInfoError") {
return (
<div className={cx("row")}>
<span>{props.error.message}</span>
</div>
);
}
const error = props.timeout ? "a timeout" : "an unexpected error";
return (
<div className={cx("row")}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import {
import { cockroach } from "src/js/protos";
import {
generateTableID,
refreshDatabases,
refreshDatabaseDetails,
refreshTableStats,
refreshDatabases,
refreshNodes,
refreshSettings,
refreshTableStats,
} from "src/redux/apiReducers";
import { AdminUIState } from "src/redux/state";
import { FixLong } from "src/util/fixLong";
Expand Down Expand Up @@ -75,7 +75,7 @@ const searchLocalSetting = new LocalSetting(
);

const selectDatabases = createSelector(
(state: AdminUIState) => state.cachedData.databases.data?.databases,
(state: AdminUIState) => state.cachedData.databases,
(state: AdminUIState) => state.cachedData.databaseDetails,
(state: AdminUIState) => state.cachedData.tableStats,
(state: AdminUIState) => nodeRegionsByIDSelector(state),
Expand All @@ -87,7 +87,7 @@ const selectDatabases = createSelector(
nodeRegions,
isTenant,
): DatabasesPageDataDatabase[] =>
(databases || []).map(database => {
(databases?.data?.databases || []).map(database => {
const details = databaseDetails[database];

const stats = details?.data?.stats;
Expand Down Expand Up @@ -131,10 +131,15 @@ const selectDatabases = createSelector(
);
const numIndexRecommendations = stats?.num_index_recommendations || 0;

const combinedErr = combineLoadingErrors(
details?.lastError,
databases?.lastError,
);

return {
loading: !!details?.inFlight,
loaded: !!details?.valid,
lastError: details?.lastError,
lastError: combinedErr,
name: database,
sizeInBytes: sizeInBytes,
tableCount: details?.data?.table_names?.length || 0,
Expand All @@ -152,6 +157,30 @@ const selectDatabases = createSelector(
}),
);

function combineLoadingErrors(detailsErr: Error, dbListErr: Error): Error {
if (!dbListErr) {
return detailsErr;
}

if (!detailsErr) {
return new GetDatabaseInfoError(
`Failed to load all databases. Partial results are shown. Debug info: ${dbListErr}`,
);
}

return new GetDatabaseInfoError(
`Failed to load all databases and database details. Partial results are shown. Debug info: ${dbListErr}, details error: ${detailsErr}`,
);
}

export class GetDatabaseInfoError extends Error {
constructor(message: string) {
super(message);

this.name = this.constructor.name;
}
}

export const mapStateToProps = (state: AdminUIState): DatabasesPageData => ({
loading: selectLoading(state),
loaded: selectLoaded(state),
Expand Down

0 comments on commit b97bfe7

Please sign in to comment.