This is an automated email from the ASF dual-hosted git repository.
xiangfu 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 042549dd645 Pinot ui distinguishes between instance liveness and
health (#17450)
042549dd645 is described below
commit 042549dd64508852c3e4edb24942c08b3499f720
Author: Johan Adami <[email protected]>
AuthorDate: Mon Jan 5 12:41:22 2026 -0500
Pinot ui distinguishes between instance liveness and health (#17450)
* do not query for health; show health as chip
* remove check instance health
* fix toLocaleLowerCase
* use orange for unhealthy
* remove extra conditional
---------
Co-authored-by: Johan Adami <[email protected]>
---
.../src/main/resources/app/components/Table.tsx | 15 +++++--
.../src/main/resources/app/interfaces/types.d.ts | 13 ++++++
.../main/resources/app/utils/PinotMethodUtils.ts | 49 +++++++---------------
3 files changed, 40 insertions(+), 37 deletions(-)
diff --git a/pinot-controller/src/main/resources/app/components/Table.tsx
b/pinot-controller/src/main/resources/app/components/Table.tsx
index 682949c322f..b11a61375a3 100644
--- a/pinot-controller/src/main/resources/app/components/Table.tsx
+++ b/pinot-controller/src/main/resources/app/components/Table.tsx
@@ -380,7 +380,7 @@ export default function CustomizedTables({
}, [search, timeoutId, filterSearchResults]);
const styleCell = (str: string) => {
- if (str.toLowerCase() === 'good' || str.toLowerCase() === 'online' ||
str.toLowerCase() === 'alive' || str.toLowerCase() === 'true') {
+ if (str.toLowerCase() === 'good' || str.toLowerCase() === 'healthy' ||
str.toLowerCase() === 'online' || str.toLowerCase() === 'alive' ||
str.toLowerCase() === 'true') {
return (
<StyledChip
label={str}
@@ -389,7 +389,7 @@ export default function CustomizedTables({
/>
);
}
- if (str.toLocaleLowerCase() === 'bad' || str.toLowerCase() === 'offline'
|| str.toLowerCase() === 'dead' || str.toLowerCase() === 'false') {
+ if (str.toLowerCase() === 'bad' || str.toLowerCase() === 'offline' ||
str.toLowerCase() === 'dead' || str.toLowerCase() === 'false') {
return (
<StyledChip
label={str}
@@ -398,7 +398,16 @@ export default function CustomizedTables({
/>
);
}
- if (str.toLowerCase() === 'consuming' || str.toLocaleLowerCase() ===
"partial" || str.toLocaleLowerCase() === "updating" ) {
+ if (str.toLowerCase() === 'disabled' || str.toLowerCase() === "queries
disabled" || str.toLowerCase() === 'unhealthy') {
+ return (
+ <StyledChip
+ label={str}
+ className={classes.cellStatusConsuming}
+ variant="outlined"
+ />
+ );
+ }
+ if (str.toLowerCase() === 'consuming' || str.toLowerCase() === "partial"
|| str.toLowerCase() === "updating") {
return (
<StyledChip
label={str}
diff --git a/pinot-controller/src/main/resources/app/interfaces/types.d.ts
b/pinot-controller/src/main/resources/app/interfaces/types.d.ts
index 634dccd5789..bdd9bf8eaae 100644
--- a/pinot-controller/src/main/resources/app/interfaces/types.d.ts
+++ b/pinot-controller/src/main/resources/app/interfaces/types.d.ts
@@ -24,6 +24,11 @@ declare module 'Models' {
component?: JSX.Element
}
+ export type InstanceStatusCell = {
+ value: InstanceStatus,
+ tooltip: string,
+ }
+
export type LoadingRecord = {
customRenderer: JSX.Element
}
@@ -407,6 +412,14 @@ declare module 'Models' {
DISABLE = "disable"
}
+ export const enum InstanceStatus {
+ DEAD = "Dead",
+ UNHEALTHY = "Unhealthy",
+ INSTANCE_DISABLED = "Disabled",
+ QUERIES_DISABLED = "Queries Disabled",
+ HEALTHY = "Healthy",
+ }
+
export const enum InstanceType {
BROKER = "BROKER",
CONTROLLER = "CONTROLLER",
diff --git a/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
b/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
index cb6d6643ce9..3739cecdc31 100644
--- a/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
+++ b/pinot-controller/src/main/resources/app/utils/PinotMethodUtils.ts
@@ -21,6 +21,8 @@ import jwtDecode from "jwt-decode";
import { get, each, isEqual, isArray, keys, union } from 'lodash';
import {
DataTable,
+ InstanceStatus,
+ InstanceStatusCell,
InstanceType,
RebalanceTableSegmentJob,
RebalanceTableSegmentJobs,
@@ -28,7 +30,7 @@ import {
SegmentMetadata,
SqlException,
SQLResult,
- TaskType
+ TaskType,
} from 'Models';
import moment from 'moment';
import {
@@ -184,20 +186,6 @@ const getAllInstances = () => {
});
};
-// This method is used to check the health endpoint of an instance
-// API: http://{hostname}:{port}/health
-// Expected Output: 'OK' or error
-const checkInstanceHealth = async (hostname, port) => {
- try {
- const response = await baseApi.get(`http://${hostname}:${port}/health`, {
- timeout: 5000 // 5 second timeout
- });
- return response.data === 'OK' || response.status === 200;
- } catch (error) {
- return false;
- }
-};
-
// This method is used to display instance data on cluster manager home page
// API: /instances/:instanceName
// Expected Output: {columns: [], records: []}
@@ -227,28 +215,21 @@ const getInstanceData = (instances, liveInstanceArr) => {
// Then check health endpoints for alive instances
const healthCheckPromises = instanceRecords.map(async (record) => {
+
+ let status: InstanceStatusCell = {value: InstanceStatus.DEAD, tooltip:
'Instance is not running'};
+
if (!record.isAlive) {
- return { ...record, healthStatus: 'Dead' };
+ return { ...record, healthStatus: status };
}
- // Determine which port to use for health check
- // For brokers and servers, use adminPort if available, otherwise use
main port
- const healthPort = record.adminPort && record.adminPort > 0 ?
record.adminPort : record.port;
- const isHealthy = await checkInstanceHealth(record.hostName, healthPort);
-
- let status = 'Dead';
- if (record.isAlive) {
- if (record.shutdownInProgress) {
- status = 'Shutting Down';
- } else if (!record.isEnabled) {
- status = 'Disabled';
- } else if (record.queriesDisabled) {
- status = 'Queries Disabled';
- } else if (isHealthy) {
- status = 'Healthy';
- } else {
- status = 'Unhealthy';
- }
+ if (record.shutdownInProgress) {
+ status = {value: InstanceStatus.UNHEALTHY, tooltip: 'Instance is
running but is starting up or shutting down'};
+ } else if (!record.isEnabled) {
+ status = {value: InstanceStatus.INSTANCE_DISABLED, tooltip: 'Instance
has been disabled in helix'};
+ } else if (record.queriesDisabled) {
+ status = {value: InstanceStatus.QUERIES_DISABLED, tooltip: 'Instance
running but has queries disabled'};
+ } else {
+ status = {value: InstanceStatus.HEALTHY, tooltip: 'Instance is healthy
and ready to serve requests'};
}
return { ...record, healthStatus: status };
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]