Expose extra node info from raylet stats (#6511)

This commit is contained in:
Mitchell Stern
2019-12-16 18:22:37 -08:00
committed by Philipp Moritz
parent ce1c9a87a7
commit 6cb34b699e
4 changed files with 71 additions and 21 deletions
+13
View File
@@ -87,6 +87,19 @@ export interface NodeInfoResponse {
export const getNodeInfo = () => get<NodeInfoResponse>("/api/node_info", {});
export interface RayletInfoResponse {
[ip: string]: {
extraInfo?: string;
workersStats: {
isDriver?: boolean;
pid: number;
}[];
};
}
export const getRayletInfo = () =>
get<RayletInfoResponse>("/api/raylet_info", {});
export interface ErrorsResponse {
[pid: string]: Array<{
message: string;
@@ -9,7 +9,7 @@ import TableRow from "@material-ui/core/TableRow";
import Typography from "@material-ui/core/Typography";
import React from "react";
import { connect } from "react-redux";
import { getNodeInfo } from "../../../api";
import { getNodeInfo, getRayletInfo } from "../../../api";
import { StoreState } from "../../../store";
import { dashboardActions } from "../state";
import LastUpdated from "./LastUpdated";
@@ -38,7 +38,8 @@ const styles = (theme: Theme) =>
});
const mapStateToProps = (state: StoreState) => ({
nodeInfo: state.dashboard.nodeInfo
nodeInfo: state.dashboard.nodeInfo,
rayletInfo: state.dashboard.rayletInfo
});
const mapDispatchToProps = dashboardActions;
@@ -50,8 +51,11 @@ class NodeInfo extends React.Component<
> {
refreshNodeInfo = async () => {
try {
const nodeInfo = await getNodeInfo();
this.props.setNodeInfo(nodeInfo);
const [nodeInfo, rayletInfo] = await Promise.all([
getNodeInfo(),
getRayletInfo()
]);
this.props.setNodeInfoAndRayletInfo({ nodeInfo, rayletInfo });
this.props.setError(null);
} catch (error) {
this.props.setError(error.toString());
@@ -65,9 +69,9 @@ class NodeInfo extends React.Component<
}
render() {
const { classes, nodeInfo } = this.props;
const { classes, nodeInfo, rayletInfo } = this.props;
if (nodeInfo === null) {
if (nodeInfo === null || rayletInfo === null) {
return (
<Typography className={classes.root} color="textSecondary">
Loading...
@@ -144,6 +148,7 @@ class NodeInfo extends React.Component<
<NodeRowGroup
key={client.ip}
node={client}
raylet={client.ip in rayletInfo ? rayletInfo[client.ip] : null}
logCounts={logCounts[client.ip]}
errorCounts={errorCounts[client.ip]}
initialExpanded={nodeInfo.clients.length <= 4}
@@ -7,7 +7,7 @@ import AddIcon from "@material-ui/icons/Add";
import RemoveIcon from "@material-ui/icons/Remove";
import classNames from "classnames";
import React from "react";
import { NodeInfoResponse } from "../../../api";
import { NodeInfoResponse, RayletInfoResponse } from "../../../api";
import { NodeCPU, WorkerCPU } from "./features/CPU";
import { NodeDisk, WorkerDisk } from "./features/Disk";
import { makeNodeErrors, makeWorkerErrors } from "./features/Errors";
@@ -35,6 +35,10 @@ const styles = (theme: Theme) =>
color: theme.palette.text.secondary,
fontSize: "1.5em",
verticalAlign: "middle"
},
extraInfo: {
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
whiteSpace: "pre-wrap"
}
});
@@ -43,6 +47,7 @@ type Node = ArrayType<NodeInfoResponse["clients"]>;
interface Props {
node: Node;
raylet: RayletInfoResponse[keyof RayletInfoResponse] | null;
logCounts: {
perWorker: { [pid: string]: number };
total: number;
@@ -73,7 +78,7 @@ class NodeRowGroup extends React.Component<
};
render() {
const { classes, node, logCounts, errorCounts } = this.props;
const { classes, node, raylet, logCounts, errorCounts } = this.props;
const { expanded } = this.state;
const features = [
@@ -114,17 +119,31 @@ class NodeRowGroup extends React.Component<
</TableCell>
))}
</TableRow>
{expanded &&
node.workers.map((worker, index: number) => (
<TableRow hover key={index}>
<TableCell className={classes.cell} />
{features.map(({ WorkerFeature }, index) => (
<TableCell className={classes.cell} key={index}>
<WorkerFeature node={node} worker={worker} />
{expanded && (
<React.Fragment>
{raylet !== null && raylet.extraInfo !== undefined && (
<TableRow hover>
<TableCell className={classes.cell} />
<TableCell
className={classNames(classes.cell, classes.extraInfo)}
colSpan={features.length}
>
{raylet.extraInfo}
</TableCell>
))}
</TableRow>
))}
</TableRow>
)}
{node.workers.map((worker, index: number) => (
<TableRow hover key={index}>
<TableCell className={classes.cell} />
{features.map(({ WorkerFeature }, index) => (
<TableCell className={classes.cell} key={index}>
<WorkerFeature node={node} worker={worker} />
</TableCell>
))}
</TableRow>
))}
</React.Fragment>
)}
</React.Fragment>
);
}
@@ -1,11 +1,16 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { NodeInfoResponse, RayConfigResponse } from "../../api";
import {
NodeInfoResponse,
RayConfigResponse,
RayletInfoResponse
} from "../../api";
const name = "dashboard";
interface State {
rayConfig: RayConfigResponse | null;
nodeInfo: NodeInfoResponse | null;
rayletInfo: RayletInfoResponse | null;
lastUpdatedAt: number | null;
error: string | null;
}
@@ -13,6 +18,7 @@ interface State {
const initialState: State = {
rayConfig: null,
nodeInfo: null,
rayletInfo: null,
lastUpdatedAt: null,
error: null
};
@@ -24,8 +30,15 @@ const slice = createSlice({
setRayConfig: (state, action: PayloadAction<RayConfigResponse>) => {
state.rayConfig = action.payload;
},
setNodeInfo: (state, action: PayloadAction<NodeInfoResponse>) => {
state.nodeInfo = action.payload;
setNodeInfoAndRayletInfo: (
state,
action: PayloadAction<{
nodeInfo: NodeInfoResponse;
rayletInfo: RayletInfoResponse;
}>
) => {
state.nodeInfo = action.payload.nodeInfo;
state.rayletInfo = action.payload.rayletInfo;
state.lastUpdatedAt = Date.now();
},
setError: (state, action: PayloadAction<string | null>) => {