Skip to content

Commit

Permalink
[Dashboard] Actor Table UI Optimize (ray-project#15802)
Browse files Browse the repository at this point in the history
  • Loading branch information
mxz96102 authored May 21, 2021
1 parent 0a7ba95 commit 43be599
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 49 deletions.
5 changes: 3 additions & 2 deletions dashboard/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@types/react-window": "^1.8.2",
"axios": "^0.21.1",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.3.1",
"dayjs": "^1.9.4",
"lodash": "^4.17.20",
"lowlight": "^1.14.0",
Expand All @@ -47,8 +48,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": [
Expand Down
52 changes: 21 additions & 31 deletions dashboard/client/src/components/ActorTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { Link } from "react-router-dom";
import { GlobalContext } from "../App";
import { Actor } from "../type/actor";
import { Worker } from "../type/worker";
import { longTextCut } from "../util/func";
import { useFilter } from "../util/hook";
import CopyableCollapse from "./CopyableCollapse";
import StateCounter from "./StatesCounter";
import { StatusChip } from "./StatusChip";
import RayletWorkerTable, { ExpandableTableRow } from "./WorkerTable";
Expand All @@ -34,16 +34,7 @@ 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);

return (
Expand Down Expand Up @@ -88,21 +79,6 @@ const ActorTable = ({
),
}}
/>
<TextField
style={{ margin: 8, width: 200 }}
label="Task Func Desc"
size="small"
InputProps={{
onChange: ({ target: { value } }) => {
changeFilter("functionDesc", value.trim());
},
endAdornment: (
<InputAdornment position="end">
<SearchOutlined />
</InputAdornment>
),
}}
/>
<TextField
style={{ margin: 8, width: 120 }}
label="Name"
Expand Down Expand Up @@ -137,10 +113,14 @@ const ActorTable = ({
style={{ margin: 8, width: 120 }}
label="Page Size"
size="small"
defaultValue={10}
InputProps={{
onChange: ({ target: { value } }) => {
setPageSize(Math.min(Number(value), 500) || 10);
},
endAdornment: (
<InputAdornment position="end">Per Page</InputAdornment>
),
}}
/>
</div>
Expand All @@ -161,9 +141,11 @@ const ActorTable = ({
<TableRow>
{[
"",
"ID(Num Restarts)",
"ID",
"Restart Times",
"Name",
"Task Func Desc",
"Class",
"Function",
"Job Id",
"Pid",
"IP",
Expand All @@ -181,7 +163,7 @@ const ActorTable = ({
{list.map(
({
actorId,
functionDesc,
functionDescriptor,
jobId,
pid,
address,
Expand Down Expand Up @@ -210,17 +192,25 @@ const ActorTable = ({
}
key={actorId}
>
<TableCell align="center">
<CopyableCollapse text={actorId} />
</TableCell>
<TableCell
align="center"
style={{
color: Number(numRestarts) > 0 ? orange[500] : "inherit",
}}
>
{actorId}({numRestarts})
{numRestarts}
</TableCell>
<TableCell align="center">{name}</TableCell>
<TableCell align="center">
{longTextCut(functionDesc, 60)}
{functionDescriptor?.javaFunctionDescriptor?.className}
{functionDescriptor?.pythonFunctionDescriptor?.className}
</TableCell>
<TableCell align="center">
{functionDescriptor?.javaFunctionDescriptor?.functionName}
{functionDescriptor?.pythonFunctionDescriptor?.functionName}
</TableCell>
<TableCell align="center">{jobId}</TableCell>
<TableCell align="center">{pid}</TableCell>
Expand Down
34 changes: 34 additions & 0 deletions dashboard/client/src/components/CopyableCollapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Tooltip } from "@material-ui/core";
import { CheckOutlined, FileCopyOutlined } from "@material-ui/icons";
import copy from "copy-to-clipboard";
import React, { useState } from "react";

const CopyableCollapse: React.FC<{
text: string;
length?: number;
noCollapse?: boolean;
}> = (props) => {
const { text, length = 5, noCollapse } = props;
const isTextLonger = text.length > length && !noCollapse;
const displayText = isTextLonger ? `${text.slice(0, length)}` : text;
const [copying, setCopying] = useState(false);
const Icon = copying ? CheckOutlined : FileCopyOutlined;

return (
<Tooltip title={text}>
<span style={{ display: "flex", alignItems: "center" }}>
{displayText}{" "}
<Icon
style={{ width: 12, height: 12, cursor: "pointer" }}
onClick={() => {
copy(text);
setCopying(true);
setTimeout(() => setCopying(false), 1000);
}}
/>
</span>
</Tooltip>
);
};

export default CopyableCollapse;
38 changes: 34 additions & 4 deletions dashboard/client/src/pages/actor/index.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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 (
<div className={classes.root}>
<TitleCard title="ACTORS">
<Grid container alignItems="center">
<Grid item>
Auto Refresh:{" "}
<Switch
checked={autoRefresh}
onChange={({ target: { checked } }) => setAutoRefresh(checked)}
/>
</Grid>
<Grid item>{timeStamp.format("YYYY-MM-DD HH:mm:ss")}</Grid>
</Grid>
<ActorTable actors={actors} />
</TitleCard>
</div>
Expand Down
24 changes: 12 additions & 12 deletions dashboard/client/src/type/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,4 +79,16 @@ export type Actor = {
isDetached: false;
name: string;
numRestarts: string;
functionDescriptor: {
javaFunctionDescriptor: {
className: string;
functionName: string;
signature: string;
};
pythonFunctionDescriptor: {
className: string;
functionName: string;
signature: string;
};
};
};

0 comments on commit 43be599

Please sign in to comment.