From bf97a6944b517978f57fa51ec75c9f78882a91f7 Mon Sep 17 00:00:00 2001 From: Guyang Song Date: Mon, 25 Jul 2022 18:49:48 +0800 Subject: [PATCH] [Dashboard] Actor Table UI Optimize (#26785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 多牧 --- dashboard/client/package.json | 4 +- dashboard/client/src/common/RowStyles.tsx | 20 ++++++ .../client/src/components/ActorTable.tsx | 61 +++++++++---------- dashboard/client/src/pages/actor/index.tsx | 38 ++++++++++-- dashboard/client/src/pages/node/NodeRow.tsx | 23 +------ dashboard/client/src/type/actor.ts | 24 ++++---- 6 files changed, 101 insertions(+), 69 deletions(-) create mode 100644 dashboard/client/src/common/RowStyles.tsx diff --git a/dashboard/client/package.json b/dashboard/client/package.json index a4579a0b9908..788d20b7ed15 100644 --- a/dashboard/client/package.json +++ b/dashboard/client/package.json @@ -50,8 +50,8 @@ "eject": "react-scripts eject", "lint": "npm run eslint && npm run prettier", "lint-fix": "npm run prettier -- --write && npm run eslint -- --fix", - "prettier": "prettier -c src", - "eslint": "eslint \"src/**\"" + "prettier": "./node_modules/.bin/prettier -c src/", + "eslint": "./node_modules/.bin/eslint \"src/**\"" }, "eslintConfig": { "ignorePatterns": [ diff --git a/dashboard/client/src/common/RowStyles.tsx b/dashboard/client/src/common/RowStyles.tsx new file mode 100644 index 000000000000..8f01ab463692 --- /dev/null +++ b/dashboard/client/src/common/RowStyles.tsx @@ -0,0 +1,20 @@ +import { createStyles, makeStyles } from "@material-ui/core/styles"; + +const rowStyles = makeStyles((theme) => + createStyles({ + expandCollapseIcon: { + color: theme.palette.text.secondary, + fontSize: "1.5em", + verticalAlign: "middle", + }, + idCol: { + display: "block", + width: "50px", + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap", + }, + }), +); + +export default rowStyles; diff --git a/dashboard/client/src/components/ActorTable.tsx b/dashboard/client/src/components/ActorTable.tsx index b90e5cf34a68..1930d75e778b 100644 --- a/dashboard/client/src/components/ActorTable.tsx +++ b/dashboard/client/src/components/ActorTable.tsx @@ -7,6 +7,7 @@ import { TableRow, TextField, TextFieldProps, + Tooltip, } from "@material-ui/core"; import { orange } from "@material-ui/core/colors"; import { SearchOutlined } from "@material-ui/icons"; @@ -15,9 +16,9 @@ import Pagination from "@material-ui/lab/Pagination"; import React, { useContext, useState } from "react"; import { Link } from "react-router-dom"; import { GlobalContext } from "../App"; +import rowStyles from "../common/RowStyles"; import { Actor } from "../type/actor"; import { Worker } from "../type/worker"; -import { longTextCut } from "../util/func"; import { useFilter } from "../util/hook"; import StateCounter from "./StatesCounter"; import { StatusChip } from "./StatusChip"; @@ -34,17 +35,9 @@ const ActorTable = ({ const { changeFilter, filterFunc } = useFilter(); const [pageSize, setPageSize] = useState(10); const { ipLogMap } = useContext(GlobalContext); - const actorList = Object.values(actors || {}) - .map((e) => ({ - ...e, - functionDesc: Object.values( - e.taskSpec?.functionDescriptor?.javaFunctionDescriptor || - e.taskSpec?.functionDescriptor?.pythonFunctionDescriptor || - {}, - ).join(" "), - })) - .filter(filterFunc); + const actorList = Object.values(actors || {}).filter(filterFunc); const list = actorList.slice((pageNo - 1) * pageSize, pageNo * pageSize); + const classes = rowStyles(); return ( @@ -88,21 +81,6 @@ const ActorTable = ({ ), }} /> - { - changeFilter("functionDesc", value.trim()); - }, - endAdornment: ( - - - - ), - }} - /> { setPageSize(Math.min(Number(value), 500) || 10); }, + endAdornment: ( + Per Page + ), }} /> @@ -161,9 +143,11 @@ const ActorTable = ({ {[ "", - "ID(Num Restarts)", + "ID", + "Restart Times", "Name", - "Task Func Desc", + "Class", + "Function", "Job Id", "Pid", "IP", @@ -181,7 +165,7 @@ const ActorTable = ({ {list.map( ({ actorId, - functionDesc, + functionDescriptor, jobId, pid, address, @@ -210,17 +194,32 @@ const ActorTable = ({ } key={actorId} > + + +
{actorId}
+
+
0 ? orange[500] : "inherit", }} > - {actorId}({numRestarts}) + {numRestarts} {name} - {longTextCut(functionDesc, 60)} + {functionDescriptor?.javaFunctionDescriptor?.className} + {functionDescriptor?.pythonFunctionDescriptor?.className} + + + {functionDescriptor?.javaFunctionDescriptor?.functionName} + {functionDescriptor?.pythonFunctionDescriptor?.functionName} {jobId} {pid} diff --git a/dashboard/client/src/pages/actor/index.tsx b/dashboard/client/src/pages/actor/index.tsx index cbcd264e26af..060c509467f0 100644 --- a/dashboard/client/src/pages/actor/index.tsx +++ b/dashboard/client/src/pages/actor/index.tsx @@ -1,4 +1,5 @@ -import { makeStyles } from "@material-ui/core"; +import { Grid, makeStyles, Switch } from "@material-ui/core"; +import dayjs from "dayjs"; import React, { useEffect, useState } from "react"; import ActorTable from "../../components/ActorTable"; import TitleCard from "../../components/TitleCard"; @@ -14,19 +15,48 @@ const useStyles = makeStyles((theme) => ({ const Actors = () => { const classes = useStyles(); + const [autoRefresh, setAutoRefresh] = useState(true); const [actors, setActors] = useState<{ [actorId: string]: Actor }>({}); - - useEffect(() => { + const [timeStamp, setTimeStamp] = useState(dayjs()); + const queryActor = () => getActors().then((res) => { if (res?.data?.data?.actors) { setActors(res.data.data.actors); } }); - }, []); + + useEffect(() => { + let tmo: NodeJS.Timeout; + const refreshActor = () => { + const nowTime = dayjs(); + queryActor().then(() => { + setTimeStamp(nowTime); + if (autoRefresh) { + tmo = setTimeout(refreshActor, 4000); + } + }); + }; + + refreshActor(); + + return () => { + clearTimeout(tmo); + }; + }, [autoRefresh]); return (
+ + + Auto Refresh:{" "} + setAutoRefresh(checked)} + /> + + {timeStamp.format("YYYY-MM-DD HH:mm:ss")} +
diff --git a/dashboard/client/src/pages/node/NodeRow.tsx b/dashboard/client/src/pages/node/NodeRow.tsx index 1ccf9d390637..cac8272520c4 100644 --- a/dashboard/client/src/pages/node/NodeRow.tsx +++ b/dashboard/client/src/pages/node/NodeRow.tsx @@ -1,10 +1,10 @@ import { IconButton, TableCell, TableRow, Tooltip } from "@material-ui/core"; -import { createStyles, makeStyles } from "@material-ui/core/styles"; import AddIcon from "@material-ui/icons/Add"; import RemoveIcon from "@material-ui/icons/Remove"; import { sortBy } from "lodash"; import React, { useCallback, useEffect, useRef, useState } from "react"; import { Link } from "react-router-dom"; +import rowStyles from "../../common/RowStyles"; import PercentageBar from "../../components/PercentageBar"; import { StatusChip } from "../../components/StatusChip"; import { getNodeDetail } from "../../service/node"; @@ -12,23 +12,6 @@ import { NodeDetail } from "../../type/node"; import { Worker } from "../../type/worker"; import { memoryConverter } from "../../util/converter"; -const useNodeRowStyles = makeStyles((theme) => - createStyles({ - expandCollapseIcon: { - color: theme.palette.text.secondary, - fontSize: "1.5em", - verticalAlign: "middle", - }, - idCol: { - display: "block", - width: "50px", - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap", - }, - }), -); - type NodeRowProps = Pick & { /** * Whether the node has been expanded to show workers @@ -56,7 +39,7 @@ const NodeRow = ({ node, expanded, onExpandButtonClick }: NodeRowProps) => { logUrl, } = node; - const classes = useNodeRowStyles(); + const classes = rowStyles(); const objectStoreTotalMemory = raylet.objectStoreAvailableMemory + raylet.objectStoreUsedMemory; @@ -141,7 +124,7 @@ type WorkerRowProps = { * A single row that represents the data of a Worker */ const WorkerRow = ({ node, worker }: WorkerRowProps) => { - const classes = useNodeRowStyles(); + const classes = rowStyles(); const { mem, logUrl } = node; const { diff --git a/dashboard/client/src/type/actor.ts b/dashboard/client/src/type/actor.ts index daf1df157749..71f1c7406f87 100644 --- a/dashboard/client/src/type/actor.ts +++ b/dashboard/client/src/type/actor.ts @@ -36,18 +36,6 @@ export type TaskSpec = { workerId: string; }; callerId: string; - functionDescriptor: { - javaFunctionDescriptor: { - className: string; - functionName: string; - signature: string; - }; - pythonFunctionDescriptor: { - className: string; - functionName: string; - signature: string; - }; - }; jobId: string; language: string; maxRetries: number; @@ -75,4 +63,16 @@ export type Actor = { name: string; numRestarts: string; taskSpec: TaskSpec; + functionDescriptor: { + javaFunctionDescriptor: { + className: string; + functionName: string; + signature: string; + }; + pythonFunctionDescriptor: { + className: string; + functionName: string; + signature: string; + }; + }; };