Skip to content

Commit

Permalink
Merge pull request #123 from visualDust/dev
Browse files Browse the repository at this point in the history
better stability
  • Loading branch information
visualDust authored Dec 17, 2023
2 parents 9af30a6 + b50e830 commit b10e0df
Show file tree
Hide file tree
Showing 67 changed files with 996 additions and 762 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@douyinfe/semi-icons": "^2.47.1",
"@douyinfe/semi-ui": "^2.47.1",
"@semi-bot/semi-theme-nyx-c": "^1.0.8",
"@uiw/react-json-view": "^2.0.0-alpha.10",
"echarts": "^5.4.3",
"jotai": "^2.5.1",
"nanoid": "^5.0.3",
Expand Down
44 changes: 21 additions & 23 deletions frontend/src/components/dashboard/project/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,30 @@ export function Actions() {
const { projectId, runId } = useCurrentProject();
const status = useProjectRunStatus(projectId, runId);
const actions = status?.action as ActionInfo;
const actionList = Object.entries(useMemoJSON(actions ?? {}));
const actionListMemo = Object.entries(useMemoJSON(actions ?? {}));
const [blocking, setBlocking] = useState(false);
return actions ? (
return !status ? (
<Loading size="large" />
) : !status.action ? (
<Typography.Text>
No actions (
<a target="_blank" href="https://neetbox.550w.host/docs/guide/">
docs
</a>
)
</Typography.Text>
) : (
<Space style={{ marginBottom: "20px" }} spacing="medium" wrap>
{actionList.length ? (
actionList.map(([actionName, actionOptions]) => (
<ActionItem
key={actionName}
name={actionName}
actionOptions={actionOptions}
blocking={blocking}
setBlocking={setBlocking}
/>
))
) : (
<Typography.Text>
No actions (
<a target="_blank" href="https://neetbox.550w.host/docs/guide/">
docs
</a>
)
</Typography.Text>
)}
{actionListMemo.map(([actionName, actionOptions]) => (
<ActionItem
key={actionName}
name={actionName}
actionOptions={actionOptions}
blocking={blocking}
setBlocking={setBlocking}
/>
))}
</Space>
) : (
<Loading size="large" />
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ECharts } from "../../../echarts";
import { CpuInfo } from "../../../../services/types";
import { TimeDataMapper } from "../../../../utils/timeDataMapper";
import { getTimeAxisOptions } from "./utils";
import { GraphWrapper } from "./graphWrapper";

export const CPUGraph = ({ data }: { data: TimeDataMapper<CpuInfo[]> }) => {
const cpus = data.getValue(0);
Expand All @@ -18,6 +19,7 @@ export const CPUGraph = ({ data }: { data: TimeDataMapper<CpuInfo[]> }) => {
bottom: 30,
},
title: {
left: 20,
text: `CPU (${cpus.length} threads)`,
textStyle: {
fontSize: 12,
Expand Down Expand Up @@ -56,6 +58,8 @@ export const CPUGraph = ({ data }: { data: TimeDataMapper<CpuInfo[]> }) => {
}, [cpus, data]);

return (
<ECharts initialOption={initialOption} updatingOption={updatingOption} style={{ height: "200px" }} />
<GraphWrapper title="CPU" lastValue={data.getValue(data.length - 1)}>
<ECharts initialOption={initialOption} updatingOption={updatingOption} style={{ height: "200px" }} />
</GraphWrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { ECharts } from "../../../echarts";
import { GpuInfo } from "../../../../services/types";
import { TimeDataMapper } from "../../../../utils/timeDataMapper";
import { getTimeAxisOptions } from "./utils";
import { GraphWrapper } from "./graphWrapper";

export const GPUGraph = ({ data }: { data: TimeDataMapper<GpuInfo> }) => {
const initialOption = () => {
const gpu = data.mapValue((x) => x)[0];
const gpu = data.getValue(0);
return {
backgroundColor: "transparent",
animation: false,
Expand All @@ -18,6 +19,7 @@ export const GPUGraph = ({ data }: { data: TimeDataMapper<GpuInfo> }) => {
bottom: 30,
},
title: {
left: 20,
text: `GPU${gpu.id}: ${gpu.name}`,
textStyle: {
fontSize: 12,
Expand Down Expand Up @@ -76,6 +78,8 @@ export const GPUGraph = ({ data }: { data: TimeDataMapper<GpuInfo> }) => {
}, [data]);

return (
<ECharts initialOption={initialOption} updatingOption={updatingOption} style={{ height: "200px" }} />
<GraphWrapper title="GPU" lastValue={data.getValue(data.length - 1)}>
<ECharts initialOption={initialOption} updatingOption={updatingOption} style={{ height: "200px" }} />
</GraphWrapper>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { PropsWithChildren, memo } from "react";
import { JsonPopover } from "../jsonView";

export const GraphWrapper = memo(
({ title, lastValue, children }: PropsWithChildren<{ title: string; lastValue: any }>) => {
return (
<div style={{ position: "relative" }}>
{children}
<JsonPopover
title={title}
value={lastValue}
position="right"
style={{ position: "absolute", left: 5, top: 3 }}
/>
</div>
);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ECharts } from "../../../echarts";
import { RamInfo } from "../../../../services/types";
import { TimeDataMapper } from "../../../../utils/timeDataMapper";
import { getTimeAxisOptions } from "./utils";
import { GraphWrapper } from "./graphWrapper";

export const RAMGraph = ({ data }: { data: TimeDataMapper<RamInfo> }) => {
const initialOption = () => {
Expand All @@ -13,6 +14,7 @@ export const RAMGraph = ({ data }: { data: TimeDataMapper<RamInfo> }) => {
trigger: "axis",
},
title: {
left: 20,
text: `RAM`,
textStyle: {
fontSize: 12,
Expand Down Expand Up @@ -59,6 +61,8 @@ export const RAMGraph = ({ data }: { data: TimeDataMapper<RamInfo> }) => {
}, [data]);

return (
<ECharts initialOption={initialOption} updatingOption={updatingOption} style={{ height: "200px" }} />
<GraphWrapper title="Memory" lastValue={data.getValue(data.length - 1)}>
<ECharts initialOption={initialOption} updatingOption={updatingOption} style={{ height: "200px" }} />
</GraphWrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TimeDataMapper } from "../../../../utils/timeDataMapper";

const viewRangeSeconds = 300;
const dataInterval = 2;
export const fetchDataCount = Math.ceil(viewRangeSeconds / dataInterval);
export const fetchDataCount = Math.ceil((viewRangeSeconds / dataInterval) * 1.1);

export function getTimeAxisOptions(mapper: TimeDataMapper) {
const latestTime = new Date(mapper.data[mapper.data.length - 1].timestamp).getTime();
Expand Down
40 changes: 40 additions & 0 deletions frontend/src/components/dashboard/project/hyperParams.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { memo } from "react";
import { Popover, Space, Typography } from "@douyinfe/semi-ui";
import { IconInfoCircle } from "@douyinfe/semi-icons";
import { useProjectRunStatus } from "../../../hooks/useProject";
import Loading from "../../loading";
import { JsonViewThemed } from "./jsonView";

export const HyperParams = memo(({ projectId, runId, trigger = "click", position }: any) => {
return (
<Popover
showArrow
trigger={trigger}
position={position}
content={<HyperParamsContent projectId={projectId} runId={runId} />}
>
<IconInfoCircle />
</Popover>
);
});

const HyperParamsContent = memo(({ projectId, runId }: any) => {
const runStatus = useProjectRunStatus(projectId, runId);
const value = runStatus?.hyperparameters;
return (
<Space vertical>
<Typography.Text type="primary">Hyperparameter</Typography.Text>
{!runStatus ? (
<Loading />
) : value == null ? (
<Typography.Text type="tertiary">N/A</Typography.Text>
) : (
<JsonViewThemed
style={{ minWidth: 200, width: 400, maxHeight: "70vh", overflow: "auto" }}
value={value}
displayDataTypes={false}
/>
)}
</Space>
);
});
4 changes: 3 additions & 1 deletion frontend/src/components/dashboard/project/images.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const Images = memo(() => {
export const AllImageViewers = memo(() => {
const { projectId, runId } = useCurrentProject()!;
const series = useProjectSeries(projectId, runId!, "image");
return series?.map((s) => <SeriesViewer key={s} series={s} />) ?? <Loading text="Images loading" />;
return (
series?.map((s) => <SeriesViewer key={s} series={s} />) ?? <Loading text="Images loading" vertical />
);
});

const SeriesViewer = memo(({ series }: { series: string }) => {
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/dashboard/project/jsonView.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.w-json-view-container {
padding-left: 1em;
}

span[style="display: inline-flex; align-items: center;"] {
/* position: absolute; */
transform: translate(-1em, 0);
}
57 changes: 57 additions & 0 deletions frontend/src/components/dashboard/project/jsonView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import JsonView from "@uiw/react-json-view";
// eslint-disable-next-line import/no-unresolved
import { githubDarkTheme } from "@uiw/react-json-view/githubDark";
import { CSSProperties, memo } from "react";
import { Popover, Space, Typography } from "@douyinfe/semi-ui";
import { IconCode, IconCodeStroked } from "@douyinfe/semi-icons";

Check warning on line 6 in frontend/src/components/dashboard/project/jsonView.tsx

View workflow job for this annotation

GitHub Actions / build

'IconCode' is defined but never used
import { Position } from "@douyinfe/semi-ui/lib/es/tooltip";
import { useTheme } from "../../../hooks/useTheme";
import "./jsonView.css";

export const JsonViewThemed = memo((props: any) => {
const { darkMode } = useTheme();
return (
<JsonView
displayDataTypes={false}
{...props}
style={{
minWidth: 200,
width: 400,
maxHeight: "60vh",
overflow: "auto",
...props?.style,
...(darkMode ? githubDarkTheme : null),
background: "transparent",
}}
/>
);
});

export const JsonPopover = memo(
({
value,
title,
position,
style,
}: {
value: any;
title?: string;
position?: Position;
style?: CSSProperties;
}) => {
return (
<Popover
showArrow
position={position}
content={
<Space vertical>
{title && <Typography.Text>{title}</Typography.Text>}
<JsonViewThemed value={value} />
</Space>
}
>
<IconCodeStroked style={{ color: "var(--semi-color-tertiary)", ...style }} />
</Popover>
);
},
);
7 changes: 7 additions & 0 deletions frontend/src/components/dashboard/project/platformProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IconCopy } from "@douyinfe/semi-icons";
import { useMemoJSON } from "../../../hooks/useMemoJSON";
import { useCurrentProject, useProjectRunStatus } from "../../../hooks/useProject";
import { PlatformInfo } from "../../../services/types";
import { JsonPopover } from "./jsonView";

const PropCard = memo(({ propName, propValue }: { propName: string; propValue: PlatformInfo[string] }) => {
const { Text } = Typography;
Expand Down Expand Up @@ -73,3 +74,9 @@ export default function PlatformProps(): React.JSX.Element {
</div>
);
}

export function PlatformTitleJson() {
const { projectId, runId } = useCurrentProject();
const runStatus = useProjectRunStatus(projectId, runId);
return <JsonPopover value={runStatus?.platform} position="right" />;
}
18 changes: 15 additions & 3 deletions frontend/src/components/dashboard/project/runSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Space, Select, Tag, Button, Modal, Form, Toast } from "@douyinfe/semi-ui";
import { IconDelete, IconEdit } from "@douyinfe/semi-icons";
import { FormApi } from "@douyinfe/semi-ui/lib/es/form";
import { useNavigate } from "react-router-dom";
import Loading from "../../loading";
import { useCurrentProject, useProjectRunIds } from "../../../hooks/useProject";
import { useCurrentProject } from "../../../hooks/useProject";
import { fetcher } from "../../../services/api";
import { HyperParams } from "./hyperParams";

export const RunSelect = memo((props: any) => {
const { setRunId, runIds, mutateRunIds, projectId, runId, isOnlineRun } = props;
const navigate = useNavigate();
const items = useMemo(
() =>
[...(runIds ?? [])]
Expand Down Expand Up @@ -50,7 +53,7 @@ export const RunSelect = memo((props: any) => {
) : (
<Tag color="red">Offline</Tag>
)}
{items.find((x) => x.runid == p.value).timestamp}
{items.find((x) => x.runid == p.value)?.timestamp}
</>
)}
>
Expand Down Expand Up @@ -91,7 +94,14 @@ export const RunSelect = memo((props: any) => {
content: `Deleting run ${item.timestamp} (${item.runid})`,
centered: true,
onOk: async () => {
// await new Promise((r) => setTimeout(r, 1000));
if (item.runid === runId) {
const existedId = runIds.find((x) => x.runid !== runId);
if (existedId) {
setRunId(existedId);
} else {
navigate("/");
}
}
await fetcher(`/project/${projectId}/run/${item.runid}`, { method: "DELETE" });
mutateRunIds();
Toast.success({
Expand All @@ -103,13 +113,15 @@ export const RunSelect = memo((props: any) => {
/>
)}
{item.online ? <Tag color="green">Online</Tag> : <Tag color="red">Offline</Tag>}
<HyperParams projectId={projectId} runId={item.runid} trigger="hover" position="leftTop" />
</Select.Option>
);
})}
</Select>
) : (
<Loading height="30px" />
)}
<HyperParams projectId={projectId} runId={runId} />
{changing && <Loading height="30px" />}
<RunEditor
data={editing}
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/dashboard/project/scatters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export const Scatters = memo(() => {
export const AllScatterViewers = memo(() => {
const { projectId, runId } = useCurrentProject();
const series = useProjectSeries(projectId, runId!, "scalar");
return series?.map((s) => <ScatterViewer key={s} series={s} />) ?? <Loading text="Scalars loading" />;
return (
series?.map((s) => <ScatterViewer key={s} series={s} />) ?? <Loading text="Scalars loading" vertical />
);
});

export const ScatterViewer = memo(({ series }: { series: string }) => {
Expand Down
Loading

0 comments on commit b10e0df

Please sign in to comment.