This is an automated email from the ASF dual-hosted git repository.
jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 30f414925c fix(ui): remove redundant api calls in home page (#14295)
30f414925c is described below
commit 30f414925cac88d14f06f65e4a43b1939941472f
Author: Jayesh Choudhary <[email protected]>
AuthorDate: Thu Oct 24 22:39:45 2024 +0530
fix(ui): remove redundant api calls in home page (#14295)
---
.../app/components/AsyncInstanceTable.tsx | 85 +++++++---------------
.../app/components/Homepage/InstancesTables.tsx | 8 +-
.../src/main/resources/app/pages/HomePage.tsx | 23 ++++--
.../resources/app/pages/InstanceListingPage.tsx | 19 ++++-
.../src/main/resources/app/pages/Tenants.tsx | 22 +++++-
.../main/resources/app/utils/PinotMethodUtils.ts | 32 ++++----
6 files changed, 101 insertions(+), 88 deletions(-)
diff --git
a/pinot-controller/src/main/resources/app/components/AsyncInstanceTable.tsx
b/pinot-controller/src/main/resources/app/components/AsyncInstanceTable.tsx
index 67a0a08841..12d6b94a0c 100644
--- a/pinot-controller/src/main/resources/app/components/AsyncInstanceTable.tsx
+++ b/pinot-controller/src/main/resources/app/components/AsyncInstanceTable.tsx
@@ -19,7 +19,7 @@
import React, { useState, useEffect } from 'react';
import { get, lowerCase, mapKeys, startCase } from 'lodash';
-import { InstanceType, TableData } from 'Models';
+import { DataTable, InstanceType, TableData } from 'Models';
import CustomizedTables from './Table';
import PinotMethodUtils from '../utils/PinotMethodUtils';
import Utils from '../utils/Utils';
@@ -28,6 +28,8 @@ import Loading from './Loading';
type BaseProps = {
instanceType: InstanceType;
showInstanceDetails?: boolean;
+ instanceNames: string[] | null;
+ liveInstanceNames?: string[];
};
type ClusterProps = BaseProps & {
@@ -45,7 +47,8 @@ type Props = ClusterProps | TenantProps;
export const AsyncInstanceTable = ({
instanceType,
cluster,
- tenant,
+ instanceNames,
+ liveInstanceNames,
showInstanceDetails = false,
}: Props) => {
const instanceColumns = showInstanceDetails
@@ -55,68 +58,30 @@ export const AsyncInstanceTable = ({
Utils.getLoadingTableData(instanceColumns)
);
- const fetchInstances = async (
- instanceType: InstanceType,
- tenant?: string
- ): Promise<string[]> => {
- if (tenant) {
- if (instanceType === InstanceType.BROKER) {
- return PinotMethodUtils.getBrokerOfTenant(tenant).then(
- (brokersData) => {
- return Array.isArray(brokersData) ? brokersData : [];
- }
- );
- } else if (instanceType === InstanceType.SERVER) {
- return PinotMethodUtils.getServerOfTenant(tenant).then(
- (serversData) => {
- return Array.isArray(serversData) ? serversData : [];
- }
- );
- }
- } else {
- return fetchInstancesOfType(instanceType);
+ useEffect(() => {
+ if(instanceNames) {
+ const loadingColumns = Array(instanceColumns.length - 1).fill(Loading);
+ setInstanceData({
+ columns: instanceColumns,
+ records: instanceNames.map((name) => [name, ...loadingColumns]) || [],
+ });
}
- };
-
- const fetchInstancesOfType = async (instanceType: InstanceType) => {
- return PinotMethodUtils.getAllInstances().then((instancesData) => {
- const lowercaseInstanceData = mapKeys(instancesData, (value, key) =>
- lowerCase(key)
- );
- return get(lowercaseInstanceData, lowerCase(instanceType));
- });
- };
+ }, [instanceNames]);
useEffect(() => {
- const instances = fetchInstances(instanceType, tenant);
- if (showInstanceDetails && cluster.length > 0) {
- const instanceDetails = instances.then(async (instancesData) => {
- const liveInstanceArr = await
PinotMethodUtils.getLiveInstance(cluster);
- return PinotMethodUtils.getInstanceData(
- instancesData,
- liveInstanceArr.data
- );
- });
- instanceDetails.then((instanceDetailsData) => {
- setInstanceData(instanceDetailsData);
- });
- } else if (showInstanceDetails && cluster.length == 0) {
- instances.then((instancesData) => {
- const defaultLoadingArray = Array(4).fill(Loading);
- setInstanceData({
- columns: instanceColumns,
- records: [[instancesData[0], ...defaultLoadingArray ]],
- });
- });
- } else {
- instances.then((instancesData) => {
- setInstanceData({
- columns: instanceColumns,
- records: instancesData.map((instance) => [instance]),
- });
- });
+ // async load all the other details
+ if(showInstanceDetails && cluster && instanceNames && liveInstanceNames) {
+ fetchAdditionalInstanceDetails();
}
- }, [instanceType, cluster, tenant, showInstanceDetails]);
+ }, [showInstanceDetails, cluster, instanceNames, liveInstanceNames]);
+
+ const fetchAdditionalInstanceDetails = async () => {
+ const additionalData = await PinotMethodUtils.getInstanceData(
+ instanceNames,
+ liveInstanceNames
+ );
+ setInstanceData(additionalData);
+ }
return (
<CustomizedTables
diff --git
a/pinot-controller/src/main/resources/app/components/Homepage/InstancesTables.tsx
b/pinot-controller/src/main/resources/app/components/Homepage/InstancesTables.tsx
index 334dc0d39e..dd5621f447 100644
---
a/pinot-controller/src/main/resources/app/components/Homepage/InstancesTables.tsx
+++
b/pinot-controller/src/main/resources/app/components/Homepage/InstancesTables.tsx
@@ -20,15 +20,17 @@
import React from 'react';
import { startCase } from 'lodash';
import { AsyncInstanceTable } from '../AsyncInstanceTable';
-import { InstanceType } from 'Models';
+import { DataTable, InstanceType } from 'Models';
type Props = {
clusterName: string;
instanceType?: InstanceType;
+ instances: DataTable;
+ liveInstanceNames: string[] | null;
};
-const Instances = ({ clusterName, instanceType }: Props) => {
+const Instances = ({ clusterName, instanceType, instances, liveInstanceNames
}: Props) => {
const order = [
InstanceType.CONTROLLER,
InstanceType.BROKER,
@@ -46,6 +48,8 @@ const Instances = ({ clusterName, instanceType }: Props) => {
cluster={clusterName}
instanceType={key}
showInstanceDetails
+ instanceNames={instances?.[key] || null}
+ liveInstanceNames={liveInstanceNames || null}
/>
);
})}
diff --git a/pinot-controller/src/main/resources/app/pages/HomePage.tsx
b/pinot-controller/src/main/resources/app/pages/HomePage.tsx
index 73f16342cf..e2909b61a8 100644
--- a/pinot-controller/src/main/resources/app/pages/HomePage.tsx
+++ b/pinot-controller/src/main/resources/app/pages/HomePage.tsx
@@ -28,6 +28,7 @@ import ClusterConfig from
'../components/Homepage/ClusterConfig';
import useTaskTypesTable from '../components/Homepage/useTaskTypesTable';
import Skeleton from '@material-ui/lab/Skeleton';
import { getTenants } from '../requests';
+import { DataTable, InstanceType } from 'Models';
const useStyles = makeStyles((theme) => ({
paper: {
@@ -82,8 +83,8 @@ const HomePage = () => {
const [brokerCount, setBrokerCount] = useState(0);
const [serverCount, setServerCount] = useState(0);
const [minionCount, setMinionCount] = useState(0);
- // const [instances, setInstances] = useState<DataTable>();
-
+ const [instances, setInstances] = useState<DataTable>();
+ const [liveInstanceNames, setLiveInstanceNames] = useState<string[]>();
const [fetchingTables, setFetchingTables] = useState(true);
const [tablesCount, setTablesCount] = useState(0);
@@ -91,10 +92,11 @@ const HomePage = () => {
const fetchData = async () => {
PinotMethodUtils.getAllInstances().then((res) => {
- setControllerCount(get(res, 'Controller', []).length);
- setBrokerCount(get(res, 'Broker', []).length);
- setServerCount(get(res, 'Server', []).length);
- setMinionCount(get(res, 'Minion', []).length);
+ setControllerCount(res[InstanceType.CONTROLLER].length);
+ setBrokerCount(res[InstanceType.BROKER].length);
+ setServerCount(res[InstanceType.SERVER].length);
+ setMinionCount(res[InstanceType.MINION].length);
+ setInstances(res);
setFetchingInstances(false);
});
@@ -114,6 +116,9 @@ const HomePage = () => {
fetchClusterName().then((clusterNameRes) => {
setClusterName(clusterNameRes);
+ PinotMethodUtils.getLiveInstance(clusterNameRes).then((res) => {
+ setLiveInstanceNames(res.data || []);
+ });
});
};
@@ -203,7 +208,11 @@ const HomePage = () => {
</Grid>
<Box mb={3} />
<TenantsListing />
- <Instances clusterName={clusterName} />
+ <Instances
+ liveInstanceNames={liveInstanceNames}
+ instances={instances}
+ clusterName={clusterName}
+ />
{taskTypesTable}
<ClusterConfig />
</Grid>
diff --git
a/pinot-controller/src/main/resources/app/pages/InstanceListingPage.tsx
b/pinot-controller/src/main/resources/app/pages/InstanceListingPage.tsx
index 9d0070725c..770142fdc1 100644
--- a/pinot-controller/src/main/resources/app/pages/InstanceListingPage.tsx
+++ b/pinot-controller/src/main/resources/app/pages/InstanceListingPage.tsx
@@ -19,8 +19,7 @@
import React, {useState, useEffect} from 'react';
import { Grid, makeStyles } from '@material-ui/core';
-import { startCase, pick } from 'lodash';
-import { DataTable, InstanceType } from 'Models';
+import { DataTable } from 'Models';
import AppLoader from '../components/AppLoader';
import PinotMethodUtils from '../utils/PinotMethodUtils';
import Instances from '../components/Homepage/InstancesTables';
@@ -40,6 +39,8 @@ const InstanceListingPage = () => {
const [fetching, setFetching] = useState(true);
const [clusterName, setClusterName] = useState('');
+ const [instances, setInstances] = useState<DataTable>();
+ const [liveInstanceNames, setLiveInstanceNames] = useState<string[]>();
const fetchData = async () => {
let clusterNameRes = localStorage.getItem('pinot_ui:clusterName');
@@ -47,6 +48,13 @@ const InstanceListingPage = () => {
clusterNameRes = await PinotMethodUtils.getClusterName();
}
setClusterName(clusterNameRes);
+
+ const liveInstanceNames = await
PinotMethodUtils.getLiveInstance(clusterNameRes);
+ setLiveInstanceNames(liveInstanceNames.data || []);
+
+ const instancesList = await PinotMethodUtils.getAllInstances();
+ setInstances(instancesList);
+
setFetching(false);
};
@@ -60,7 +68,12 @@ const InstanceListingPage = () => {
<AppLoader />
) : (
<Grid item xs className={classes.gridContainer}>
- <Instances clusterName={clusterName} instanceType={instanceType} />
+ <Instances
+ liveInstanceNames={liveInstanceNames}
+ instances={instances}
+ clusterName={clusterName}
+ instanceType={instanceType}
+ />
</Grid>
);
};
diff --git a/pinot-controller/src/main/resources/app/pages/Tenants.tsx
b/pinot-controller/src/main/resources/app/pages/Tenants.tsx
index 19f61ec6e1..e43c17c36b 100644
--- a/pinot-controller/src/main/resources/app/pages/Tenants.tsx
+++ b/pinot-controller/src/main/resources/app/pages/Tenants.tsx
@@ -17,7 +17,7 @@
* under the License.
*/
-import React from 'react';
+import React, { useEffect, useState } from 'react';
import { Grid, makeStyles } from '@material-ui/core';
import { InstanceType } from 'Models';
import { RouteComponentProps } from 'react-router-dom';
@@ -25,6 +25,7 @@ import SimpleAccordion from '../components/SimpleAccordion';
import AsyncPinotTables from '../components/AsyncPinotTables';
import CustomButton from '../components/CustomButton';
import { AsyncInstanceTable } from '../components/AsyncInstanceTable';
+import PinotMethodUtils from '../utils/PinotMethodUtils';
const useStyles = makeStyles((theme) => ({
operationDiv: {
@@ -41,6 +42,23 @@ type Props = {
const TenantPage = ({ match }: RouteComponentProps<Props>) => {
const { tenantName } = match.params;
const classes = useStyles();
+ const [instanceNames, setInstanceNames] = useState({
+ [InstanceType.BROKER]: null,
+ [InstanceType.SERVER]: null,
+ })
+
+ useEffect(() => {
+ fetchInstanceData();
+ }, []);
+
+ const fetchInstanceData = async () => {
+ const brokerNames = await PinotMethodUtils.getBrokerOfTenant(tenantName)
|| [];
+ const serverNames = await PinotMethodUtils.getServerOfTenant(tenantName)
|| [];
+ setInstanceNames({
+ [InstanceType.BROKER]: Array.isArray(brokerNames) ? brokerNames : [],
+ [InstanceType.SERVER]: Array.isArray(serverNames) ? serverNames : [],
+ });
+ }
return (
<Grid
@@ -83,12 +101,14 @@ const TenantPage = ({ match }: RouteComponentProps<Props>)
=> {
<Grid container spacing={2}>
<Grid item xs={6}>
<AsyncInstanceTable
+ instanceNames={instanceNames[InstanceType.BROKER]}
instanceType={InstanceType.BROKER}
tenant={tenantName}
/>
</Grid>
<Grid item xs={6}>
<AsyncInstanceTable
+ instanceNames={instanceNames[InstanceType.SERVER]}
instanceType={InstanceType.SERVER}
tenant={tenantName}
/>
diff --git a/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
b/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
index 348751c368..4207e59f47 100644
--- a/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
+++ b/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
@@ -18,8 +18,8 @@
*/
import jwtDecode from "jwt-decode";
-import { get, map, each, isEqual, isArray, keys, union } from 'lodash';
-import { DataTable, SchemaInfo, SegmentMetadata, SqlException, SQLResult,
TableSize } from 'Models';
+import { get, each, isEqual, isArray, keys, union } from 'lodash';
+import { DataTable, InstanceType, SchemaInfo, SegmentMetadata, SqlException,
SQLResult } from 'Models';
import moment from 'moment';
import {
getTenants,
@@ -33,7 +33,6 @@ import {
getTaskTypes,
getTaskTypeDebug,
getTables,
- getTaskTypeTasks,
getTaskTypeTasksCount,
getTaskTypeState,
stopTasks,
@@ -101,7 +100,7 @@ import {
getServerToSegmentsCount
} from '../requests';
import { baseApi } from './axios-config';
-import Utils, { getDisplaySegmentStatus } from './Utils';
+import Utils from './Utils';
import { matchPath } from 'react-router';
import RouterData from '../router';
const JSONbig = require('json-bigint')({'storeAsString': true})
@@ -147,19 +146,22 @@ const getTenantsData = () => {
// This method is used to fetch all instances on cluster manager home page
// API: /instances
-// Expected Output: {Controller: ['Controller1', 'Controller2'], Broker:
['Broker1', 'Broker2']}
+// Expected Output: {CONTROLLER: ['Controller1', 'Controller2'], BROKER:
['Broker1', 'Broker2']}
const getAllInstances = () => {
return getInstances().then(({ data }) => {
- const initialVal: DataTable = {};
- // It will create instances list array like
- // {Controller: ['Controller1', 'Controller2'], Broker: ['Broker1',
'Broker2']}
- const groupedData = data.instances.reduce((r, a) => {
- const y = a.split('_');
- const key = y[0].trim();
- r[key] = [...(r[key] || []), a];
- return r;
- }, initialVal);
- return {'Controller': groupedData.Controller, ...groupedData};
+ const instanceTypeToInstancesMap: DataTable = {
+ [InstanceType.CONTROLLER]: [],
+ [InstanceType.BROKER]: [],
+ [InstanceType.SERVER]: [],
+ [InstanceType.MINION]: []
+ };
+
+ data.instances.forEach((instance) => {
+ const instanceType = instance.split('_')[0].toUpperCase();
+ instanceTypeToInstancesMap[instanceType].push(instance);
+ });
+
+ return instanceTypeToInstancesMap;
});
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]