Skip to content

Commit

Permalink
fix: fix node LoadAverage calculation (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
artemmufazalov authored Jul 3, 2024
1 parent 761b29e commit 191ac71
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/components/FullNodeViewer/FullNodeViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const FullNodeViewer = ({node, className}: FullNodeViewerProps) => {
{label: 'Rack', value: node?.Rack},
);

const averageInfo = node?.LoadAverage?.map((load, loadIndex) => ({
const averageInfo = node?.LoadAveragePercents?.map((load, loadIndex) => ({
label: LOAD_AVERAGE_TIME_INTERVALS[loadIndex],
value: (
<ProgressViewer value={load} percents={true} colorizeProgress={true} capacity={100} />
Expand Down
13 changes: 6 additions & 7 deletions src/containers/Nodes/getNodesColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,12 @@ const cpuColumn: NodesColumn = {
const loadAverageColumn: NodesColumn = {
name: NODES_COLUMNS_IDS.LoadAverage,
header: 'Load average',
sortAccessor: ({LoadAverage = []}) =>
LoadAverage.slice(0, 1).reduce((acc, item) => acc + item, 0),
sortAccessor: ({LoadAveragePercents = []}) => LoadAveragePercents[0],
defaultOrder: DataTable.DESCENDING,
render: ({row}) =>
row.LoadAverage && row.LoadAverage.length > 0 ? (
row.LoadAveragePercents && row.LoadAveragePercents.length > 0 ? (
<ProgressViewer
value={row.LoadAverage[0]}
value={row.LoadAveragePercents[0]}
percents={true}
colorizeProgress={true}
capacity={100}
Expand Down Expand Up @@ -179,10 +178,10 @@ const topNodesLoadAverageColumn: NodesColumn = {
name: NODES_COLUMNS_IDS.TopNodesLoadAverage,
header: 'Load',
render: ({row}) =>
row.LoadAverage && row.LoadAverage.length > 0 ? (
row.LoadAveragePercents && row.LoadAveragePercents.length > 0 ? (
<UsageLabel
value={row.LoadAverage[0].toFixed()}
theme={getLoadSeverityForNode(row.LoadAverage[0])}
value={row.LoadAveragePercents[0].toFixed()}
theme={getLoadSeverityForNode(row.LoadAveragePercents[0])}
/>
) : (
'—'
Expand Down
11 changes: 5 additions & 6 deletions src/containers/Versions/NodesTable/NodesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ const columns: Column<PreparedClusterNode>[] = [
align: DataTable.LEFT,
},
{
name: 'uptime',
name: 'Uptime',
header: 'Uptime',
sortAccessor: ({StartTime}) => StartTime && -StartTime,
width: 120,
align: DataTable.LEFT,
render: ({row}) => row.uptime,
render: ({row}) => row.Uptime,
},
{
name: 'MemoryUsed',
Expand Down Expand Up @@ -90,15 +90,14 @@ const columns: Column<PreparedClusterNode>[] = [
{
name: 'LoadAverage',
header: 'Load average',
sortAccessor: ({LoadAverage = []}) =>
LoadAverage.slice(0, 1).reduce((acc, item) => acc + item, 0),
sortAccessor: ({LoadAveragePercents = []}) => LoadAveragePercents[0],
defaultOrder: DataTable.DESCENDING,
width: 140,
resizeMinWidth: 140,
render: ({row}) =>
row.LoadAverage && row.LoadAverage.length > 0 ? (
row.LoadAveragePercents && row.LoadAveragePercents.length > 0 ? (
<ProgressViewer
value={row.LoadAverage[0]}
value={row.LoadAveragePercents[0]}
percents={true}
capacity={100}
colorizeProgress={true}
Expand Down
15 changes: 4 additions & 11 deletions src/store/reducers/clusterNodes/clusterNodes.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import type {TSystemStateInfo} from '../../../types/api/nodes';
import {calcUptime} from '../../../utils/dataFormatters/dataFormatters';
import type {PreparedNodeSystemState} from '../../../utils/nodes';
import {prepareNodeSystemState} from '../../../utils/nodes';
import {api} from '../api';

export interface PreparedClusterNode extends TSystemStateInfo {
uptime: string;
}
export type PreparedClusterNode = PreparedNodeSystemState;

export const clusterNodesApi = api.injectEndpoints({
endpoints: (builder) => ({
Expand All @@ -13,12 +11,7 @@ export const clusterNodesApi = api.injectEndpoints({
try {
const result = await window.api.getClusterNodes();
const {SystemStateInfo: nodes = []} = result;
const data: PreparedClusterNode[] = nodes.map((node) => {
return {
...node,
uptime: calcUptime(node.StartTime),
};
});
const data: PreparedClusterNode[] = nodes.map(prepareNodeSystemState);
return {data};
} catch (error) {
return {error};
Expand Down
1 change: 1 addition & 0 deletions src/store/reducers/nodes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface NodesPreparedEntity {

PoolStats?: TPoolStats[];
LoadAverage?: number[];
LoadAveragePercents?: number[];
Tablets?: TFullTabletStateInfo[] | TComputeTabletStateInfo[];
Endpoints?: TEndpoint[];

Expand Down
5 changes: 3 additions & 2 deletions src/store/reducers/nodes/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import type {TComputeInfo, TComputeNodeInfo, TComputeTenantInfo} from '../../../
import type {TNodesInfo} from '../../../types/api/nodes';
import {calcUptime} from '../../../utils/dataFormatters/dataFormatters';
import {generateEvaluator} from '../../../utils/generateEvaluator';
import {prepareNodeSystemState} from '../../../utils/nodes';
import {calculateLoadAveragePercents, prepareNodeSystemState} from '../../../utils/nodes';

import type {NodesHandledResponse, NodesPreparedEntity} from './types';

const prepareComputeNode = (node: TComputeNodeInfo, tenantName?: string) => {
const prepareComputeNode = (node: TComputeNodeInfo, tenantName?: string): NodesPreparedEntity => {
return {
...node,
// v2 response has tenant name, v1 - doesn't
TenantName: node.Tenant ?? tenantName,
SystemState: node?.Overall,
Uptime: calcUptime(node?.StartTime),
LoadAveragePercents: calculateLoadAveragePercents(node),

DC: node.DataCenter,
};
Expand Down
19 changes: 19 additions & 0 deletions src/utils/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {z} from 'zod';
import type {NodesPreparedEntity} from '../store/reducers/nodes/types';
import {ProblemFilterValues} from '../store/reducers/settings/settings';
import type {ProblemFilterValue} from '../store/reducers/settings/types';
import type {TComputeNodeInfo} from '../types/api/compute';
import {EFlag} from '../types/api/enums';
import type {TSystemStateInfo} from '../types/api/nodes';
import type {TNodeInfo} from '../types/api/nodesList';
Expand All @@ -12,6 +13,8 @@ import type {NodesMap} from '../types/store/nodesList';
import {HOUR_IN_SECONDS} from './constants';
import {calcUptime} from './dataFormatters/dataFormatters';

import {valueIsDefined} from '.';

export enum NodesUptimeFilterValues {
'All' = 'All',
'SmallUptime' = 'SmallUptime',
Expand All @@ -38,9 +41,22 @@ export const prepareNodesMap = (nodesList?: TNodeInfo[]) => {
}, new Map());
};

export function calculateLoadAveragePercents(node: TSystemStateInfo | TComputeNodeInfo = {}) {
const {LoadAverage, NumberOfCpus} = node;

if (!valueIsDefined(LoadAverage) || !valueIsDefined(NumberOfCpus)) {
return undefined;
}

return LoadAverage.map((value) => {
return (value * 100) / NumberOfCpus;
});
}

export interface PreparedNodeSystemState extends TSystemStateInfo {
Rack?: string;
DC?: string;
LoadAveragePercents?: number[];
Uptime: string;
}

Expand All @@ -53,11 +69,14 @@ export const prepareNodeSystemState = (

const Uptime = calcUptime(systemState.StartTime);

const LoadAveragePercents = calculateLoadAveragePercents(systemState);

return {
...systemState,
Rack,
DC,
Uptime,
LoadAveragePercents,
};
};

Expand Down

0 comments on commit 191ac71

Please sign in to comment.