Browse Source

fix: 列表运行时长和详情运行时长不一致

pull/226/head
cp3hnu 8 months ago
parent
commit
9c62812424
19 changed files with 106 additions and 155 deletions
  1. +2
    -3
      react-ui/src/pages/ActiveLearn/Instance/index.tsx
  2. +1
    -5
      react-ui/src/pages/ActiveLearn/components/ActiveLearnBasic/index.tsx
  3. +1
    -2
      react-ui/src/pages/AutoML/Instance/index.tsx
  4. +2
    -5
      react-ui/src/pages/AutoML/components/AutoMLBasic/index.tsx
  5. +1
    -8
      react-ui/src/pages/AutoML/components/ExperimentInstanceList/index.tsx
  6. +16
    -20
      react-ui/src/pages/AutoML/components/ExperimentInstanceList/instance.tsx
  7. +1
    -1
      react-ui/src/pages/AutoML/components/ExperimentList/config.ts
  8. +4
    -5
      react-ui/src/pages/AutoML/components/ExperimentRunBasic/index.tsx
  9. +1
    -8
      react-ui/src/pages/Experiment/components/ExperimentInstanceList/index.tsx
  10. +16
    -20
      react-ui/src/pages/Experiment/components/ExperimentInstanceList/instance.tsx
  11. +27
    -21
      react-ui/src/pages/Experiment/index.jsx
  12. +1
    -2
      react-ui/src/pages/HyperParameter/Instance/index.tsx
  13. +1
    -50
      react-ui/src/pages/HyperParameter/components/HyperParameterBasic/index.tsx
  14. +2
    -1
      react-ui/src/services/activeLearn/index.js
  15. +2
    -1
      react-ui/src/services/autoML/index.js
  16. +2
    -1
      react-ui/src/services/experiment/index.js
  17. +2
    -1
      react-ui/src/services/hyperParameter/index.js
  18. +1
    -0
      react-ui/src/types.ts
  19. +23
    -1
      react-ui/src/utils/index.ts

+ 2
- 3
react-ui/src/pages/ActiveLearn/Instance/index.tsx View File

@@ -51,13 +51,12 @@ function ActiveLearnInstance() {
const [res] = await to(getActiveLearnInsReq(instanceId));
if (res && res.data) {
const info = res.data as ActiveLearnInstanceData;
const { param, node_status, argo_ins_name, argo_ins_ns, status, create_time } = info;
const { param, node_status, argo_ins_name, argo_ins_ns, status } = info;
// 解析配置参数
const paramJson = parseJsonText(param);
if (paramJson) {
setExperimentInfo({
...paramJson.data,
create_time,
});
}

@@ -69,7 +68,7 @@ function ActiveLearnInstance() {
return;
}

// 进行节点状态
// 设置节点状态
const nodeStatusJson = parseJsonText(node_status);
if (nodeStatusJson) {
setNodes(nodeStatusJson);


+ 1
- 5
react-ui/src/pages/ActiveLearn/components/ActiveLearnBasic/index.tsx View File

@@ -213,11 +213,7 @@ function BasicInfo({
return (
<div className={classNames(styles['active-learn-basic'], className)}>
{isInstance && runStatus && (
<ExperimentRunBasic
create_time={info?.create_time}
runStatus={runStatus}
instanceStatus={instanceStatus}
/>
<ExperimentRunBasic runStatus={runStatus} instanceStatus={instanceStatus} />
)}
{!isInstance && (
<ConfigInfo


+ 1
- 2
react-ui/src/pages/AutoML/Instance/index.tsx View File

@@ -51,7 +51,7 @@ function AutoMLInstance() {
const [res] = await to(getExperimentInsReq(instanceId));
if (res && res.data) {
const info = res.data as AutoMLInstanceData;
const { param, node_status, argo_ins_name, argo_ins_ns, status, create_time, type } = info;
const { param, node_status, argo_ins_name, argo_ins_ns, status, type } = info;

setType(type);
// 解析配置参数
@@ -59,7 +59,6 @@ function AutoMLInstance() {
if (paramJson) {
setAutoMLInfo({
...paramJson.data,
create_time,
type,
});
}


+ 2
- 5
react-ui/src/pages/AutoML/components/AutoMLBasic/index.tsx View File

@@ -40,6 +40,7 @@ type AutoMLBasicProps = {
isInstance?: boolean;
runStatus?: NodeStatus;
instanceStatus?: ExperimentStatus;
instanceCreateTime?: string;
};

function AutoMLBasic({
@@ -293,11 +294,7 @@ function AutoMLBasic({
return (
<div className={classNames(styles['auto-ml-basic'], className)}>
{isInstance && runStatus && (
<ExperimentRunBasic
create_time={info?.create_time}
runStatus={runStatus}
instanceStatus={instanceStatus}
/>
<ExperimentRunBasic runStatus={runStatus} instanceStatus={instanceStatus} />
)}
{!isInstance && (
<ConfigInfo


+ 1
- 8
react-ui/src/pages/AutoML/components/ExperimentInstanceList/index.tsx View File

@@ -182,14 +182,7 @@ function ExperimentInstanceList({
>
{index + 1}
</a>
<ExperimentInstanceComponent
create_time={item.create_time}
finish_time={item.finish_time}
status={item.status as ExperimentStatus}
argo_ins_name={item.argo_ins_name}
argo_ins_ns={item.argo_ins_ns}
experimentInsId={item.id}
></ExperimentInstanceComponent>
<ExperimentInstanceComponent instance={item}></ExperimentInstanceComponent>
<div className={styles.operation}>
<Button
type="link"


+ 16
- 20
react-ui/src/pages/AutoML/components/ExperimentInstanceList/instance.tsx View File

@@ -2,29 +2,25 @@ import RunDuration from '@/components/RunDuration';
import { ExperimentStatus } from '@/enums';
import { useSSE, type MessageHandler } from '@/hooks/useSSE';
import { experimentStatusInfo } from '@/pages/Experiment/status';
import { ExperimentInstance, NodeStatus } from '@/types';
import { getWorkflowStatus } from '@/utils';
import { ExperimentCompleted } from '@/utils/constant';
import { formatDate } from '@/utils/date';
import { Typography } from 'antd';
import React, { useCallback } from 'react';
import styles from './index.less';

type ExperimentInstanceProps = {
create_time?: string;
finish_time?: string;
status: ExperimentStatus;
argo_ins_name: string;
argo_ins_ns: string;
experimentInsId: number;
type ExperimentInstanceComponentProps = {
instance: ExperimentInstance;
};

function ExperimentInstance({
create_time,
finish_time,
status,
argo_ins_name,
argo_ins_ns,
experimentInsId,
}: ExperimentInstanceProps) {
function ExperimentInstanceComponent({ instance }: ExperimentInstanceComponentProps) {
const { id, argo_ins_name, argo_ins_ns, node_status, create_time, finish_time } = instance;
const status = instance.status as ExperimentStatus;
const workflowStatus = getWorkflowStatus(node_status) as NodeStatus | undefined;
const createTime = workflowStatus?.startedAt ?? create_time;
const finishTime = workflowStatus?.finishedAt ?? finish_time;

const handleSSEMessage: MessageHandler = useCallback(
(experimentInsId: number, status: string, finish_time: string) => {
window.postMessage({
@@ -38,16 +34,16 @@ function ExperimentInstance({
},
[],
);
useSSE(experimentInsId, status, argo_ins_name, argo_ins_ns, handleSSEMessage);
useSSE(id, status, argo_ins_name, argo_ins_ns, handleSSEMessage);

return (
<React.Fragment>
<div className={styles.description}>
<RunDuration createTime={create_time} finishTime={finish_time} />
<RunDuration createTime={createTime} finishTime={finishTime} />
</div>
<div className={styles.startTime}>
<Typography.Text ellipsis={{ tooltip: formatDate(create_time) }}>
{formatDate(create_time)}
<Typography.Text ellipsis={{ tooltip: formatDate(createTime) }}>
{formatDate(createTime)}
</Typography.Text>
</div>
<div className={styles.statusBox}>
@@ -65,4 +61,4 @@ function ExperimentInstance({
);
}

export default ExperimentInstance;
export default ExperimentInstanceComponent;

+ 1
- 1
react-ui/src/pages/AutoML/components/ExperimentList/config.ts View File

@@ -39,7 +39,7 @@ export enum ExperimentListType {
}

type ExperimentListInfo = {
getListReq: (params: any) => Promise<any>; // 获取列表
getListReq: (params: any, skipLoading?: boolean) => Promise<any>; // 获取列表
getInsListReq: (params: any) => Promise<any>; // 获取实例列表
deleteRecordReq: (params: any) => Promise<any>; // 删除
runRecordReq: (params: any) => Promise<any>; // 运行


+ 4
- 5
react-ui/src/pages/AutoML/components/ExperimentRunBasic/index.tsx View File

@@ -8,12 +8,11 @@ import { Flex } from 'antd';
import { useMemo } from 'react';

type ExperimentRunBasicProps = {
create_time?: string;
runStatus?: NodeStatus;
instanceStatus?: ExperimentStatus;
};

function ExperimentRunBasic({ create_time, runStatus, instanceStatus }: ExperimentRunBasicProps) {
function ExperimentRunBasic({ runStatus, instanceStatus }: ExperimentRunBasicProps) {
const instanceDatas = useMemo(() => {
if (!runStatus) {
return [];
@@ -26,11 +25,11 @@ function ExperimentRunBasic({ create_time, runStatus, instanceStatus }: Experime
return [
{
label: '启动时间',
value: formatDate(create_time),
value: formatDate(runStatus.startedAt),
},
{
label: '执行时长',
value: <RunDuration createTime={create_time} finishTime={runStatus.finishedAt} />,
value: <RunDuration createTime={runStatus.startedAt} finishTime={runStatus.finishedAt} />,
},
{
label: '状态',
@@ -55,7 +54,7 @@ function ExperimentRunBasic({ create_time, runStatus, instanceStatus }: Experime
),
},
];
}, [runStatus, create_time, instanceStatus]);
}, [runStatus, instanceStatus]);

return (
<ConfigInfo


+ 1
- 8
react-ui/src/pages/Experiment/components/ExperimentInstanceList/index.tsx View File

@@ -197,14 +197,7 @@ function ExperimentInstanceList({
)}
</div>

<ExperimentInstanceComponent
create_time={item.create_time}
finish_time={item.finish_time}
status={item.status as ExperimentStatus}
argo_ins_name={item.argo_ins_name}
argo_ins_ns={item.argo_ins_ns}
experimentInsId={item.id}
></ExperimentInstanceComponent>
<ExperimentInstanceComponent instance={item}></ExperimentInstanceComponent>

<div className={styles.operation}>
<Button


+ 16
- 20
react-ui/src/pages/Experiment/components/ExperimentInstanceList/instance.tsx View File

@@ -2,29 +2,25 @@ import RunDuration from '@/components/RunDuration';
import { ExperimentStatus } from '@/enums';
import { useSSE, type MessageHandler } from '@/hooks/useSSE';
import { experimentStatusInfo } from '@/pages/Experiment/status';
import { ExperimentInstance, NodeStatus } from '@/types';
import { getWorkflowStatus } from '@/utils';
import { ExperimentCompleted } from '@/utils/constant';
import { formatDate } from '@/utils/date';
import { Typography } from 'antd';
import React, { useCallback } from 'react';
import styles from './index.less';

type ExperimentInstanceProps = {
create_time?: string;
finish_time?: string;
status: ExperimentStatus;
argo_ins_name: string;
argo_ins_ns: string;
experimentInsId: number;
type ExperimentInstanceComponentProps = {
instance: ExperimentInstance;
};

function ExperimentInstance({
create_time,
finish_time,
status,
argo_ins_name,
argo_ins_ns,
experimentInsId,
}: ExperimentInstanceProps) {
function ExperimentInstanceComponent({ instance }: ExperimentInstanceComponentProps) {
const { id, argo_ins_name, argo_ins_ns, nodes_status, create_time, finish_time } = instance;
const status = instance.status as ExperimentStatus;
const workflowStatus = getWorkflowStatus(nodes_status) as NodeStatus | undefined;
const createTime = workflowStatus?.startedAt ?? create_time;
const finishTime = workflowStatus?.finishedAt ?? finish_time;

const handleSSEMessage: MessageHandler = useCallback(
(experimentInsId: number, status: string, finish_time: string) => {
window.postMessage({
@@ -38,17 +34,17 @@ function ExperimentInstance({
},
[],
);
useSSE(experimentInsId, status, argo_ins_name, argo_ins_ns, handleSSEMessage);
useSSE(id, status, argo_ins_name, argo_ins_ns, handleSSEMessage);

return (
<React.Fragment>
<div className={styles.description}>
<div style={{ width: '50%' }}>
<RunDuration createTime={create_time} finishTime={finish_time} />
<RunDuration createTime={createTime} finishTime={finishTime} />
</div>
<div style={{ width: '50%' }} className={styles.startTime}>
<Typography.Text ellipsis={{ tooltip: formatDate(create_time) }}>
{formatDate(create_time)}
<Typography.Text ellipsis={{ tooltip: formatDate(createTime) }}>
{formatDate(createTime)}
</Typography.Text>
</div>
</div>
@@ -67,4 +63,4 @@ function ExperimentInstance({
);
}

export default ExperimentInstance;
export default ExperimentInstanceComponent;

+ 27
- 21
react-ui/src/pages/Experiment/index.jsx View File

@@ -60,29 +60,35 @@ function Experiment() {
const timerRef = useRef();

// 获取实验列表
const getExperimentList = useCallback(async () => {
const params = {
page: pagination.current - 1,
size: pagination.pageSize,
name: searchText || undefined,
};
const [res] = await to(getExperiment(params));
if (res && res.data && Array.isArray(res.data.content)) {
setExperimentList(
res.data.content.map((item) => {
return { ...item, key: item.id };
}),
);

setTotal(res.data.totalElements);
}
}, [pagination, searchText]);
const getExperimentList = useCallback(
async (skipLoading) => {
const params = {
page: pagination.current - 1,
size: pagination.pageSize,
name: searchText || undefined,
};
const [res] = await to(getExperiment(params, skipLoading));
if (res && res.data && Array.isArray(res.data.content)) {
setExperimentList(
res.data.content.map((item) => {
return { ...item, key: item.id };
}),
);

setTotal(res.data.totalElements);
}
},
[pagination, searchText],
);

// 刷新实验列表状态,
// 目前是直接刷新实验列表,后续需要优化,只刷新状态
const refreshExperimentList = useCallback(() => {
getExperimentList();
}, [getExperimentList]);
const refreshExperimentList = useCallback(
(skipLoading) => {
getExperimentList(skipLoading);
},
[getExperimentList],
);

// 获取流水线列表
useEffect(() => {
@@ -137,7 +143,7 @@ function Experiment() {
}

timerRef.current = setTimeout(() => {
refreshExperimentList();
refreshExperimentList(true);
}, 10000);
}
};


+ 1
- 2
react-ui/src/pages/HyperParameter/Instance/index.tsx View File

@@ -51,7 +51,7 @@ function HyperParameterInstance() {
const [res] = await to(getRayInsReq(instanceId));
if (res && res.data) {
const info = res.data as HyperParameterInstanceData;
const { param, node_status, argo_ins_name, argo_ins_ns, status, create_time } = info;
const { param, node_status, argo_ins_name, argo_ins_ns, status } = info;
// 解析配置参数
const paramJson = parseJsonText(param).data;
if (paramJson) {
@@ -72,7 +72,6 @@ function HyperParameterInstance() {
}
setExperimentInfo({
...paramJson,
create_time,
});
}



+ 1
- 50
react-ui/src/pages/HyperParameter/components/HyperParameterBasic/index.tsx View File

@@ -1,9 +1,7 @@
import ConfigInfo, { type BasicInfoData } from '@/components/ConfigInfo';
import RunDuration from '@/components/RunDuration';
import { ExperimentStatus, hyperParameterOptimizedMode } from '@/enums';
import { useComputingResource } from '@/hooks/useComputingResource';
import ExperimentRunBasic from '@/pages/AutoML/components/ExperimentRunBasic';
import { experimentStatusInfo } from '@/pages/Experiment/status';
import {
schedulerAlgorithms,
searchAlgorithms,
@@ -18,7 +16,6 @@ import {
formatMirror,
formatModel,
} from '@/utils/format';
import { Flex } from 'antd';
import classNames from 'classnames';
import { useMemo } from 'react';
import ParameterInfo from '../ParameterInfo';
@@ -145,56 +142,10 @@ function HyperParameterBasic({
];
}, [info, getResourceDescription]);

const instanceDatas = useMemo(() => {
if (!info || !runStatus) {
return [];
}

return [
{
label: '启动时间',
value: formatDate(info.create_time),
ellipsis: true,
},
{
label: '执行时长',
value: <RunDuration createTime={info.create_time} finishTime={runStatus.finishedAt} />,
ellipsis: true,
},
{
label: '状态',
value: (
<Flex align="center">
<img
style={{ width: '17px', marginRight: '7px' }}
src={experimentStatusInfo[runStatus.phase]?.icon}
draggable={false}
alt=""
/>
<div
style={{
color: experimentStatusInfo[runStatus?.phase]?.color,
fontSize: '15px',
lineHeight: 1.6,
}}
>
{experimentStatusInfo[runStatus?.phase]?.label}
</div>
</Flex>
),
ellipsis: true,
},
];
}, [runStatus, info]);

return (
<div className={classNames(styles['hyper-parameter-basic'], className)}>
{isInstance && runStatus && (
<ExperimentRunBasic
create_time={info?.create_time}
runStatus={runStatus}
instanceStatus={instanceStatus}
/>
<ExperimentRunBasic runStatus={runStatus} instanceStatus={instanceStatus} />
)}
{!isInstance && (
<ConfigInfo


+ 2
- 1
react-ui/src/services/activeLearn/index.js View File

@@ -7,10 +7,11 @@
import { request } from '@umijs/max';

// 分页查询超参数自动寻优
export function getActiveLearnListReq(params) {
export function getActiveLearnListReq(params, skipLoading) {
return request(`/api/mmp/activeLearn`, {
method: 'GET',
params,
skipLoading
});
}



+ 2
- 1
react-ui/src/services/autoML/index.js View File

@@ -7,10 +7,11 @@
import { request } from '@umijs/max';

// 分页查询自动学习
export function getAutoMLListReq(params) {
export function getAutoMLListReq(params,skipLoading) {
return request(`/api/mmp/machineLearn`, {
method: 'GET',
params,
skipLoading,
});
}



+ 2
- 1
react-ui/src/services/experiment/index.js View File

@@ -1,9 +1,10 @@
import { request } from '@umijs/max';
// 查询实验列表
export function getExperiment(params) {
export function getExperiment(params, skipLoading) {
return request(`/api/mmp/experiment`, {
method: 'GET',
params,
skipLoading,
});
}
// 运行实验


+ 2
- 1
react-ui/src/services/hyperParameter/index.js View File

@@ -7,10 +7,11 @@
import { request } from '@umijs/max';

// 分页查询超参数自动寻优
export function getRayListReq(params) {
export function getRayListReq(params, skipLoading) {
return request(`/api/mmp/ray`, {
method: 'GET',
params,
skipLoading
});
}



+ 1
- 0
react-ui/src/types.ts View File

@@ -52,6 +52,7 @@ export type ExperimentInstance = {
nodes_result: {
[key: string]: any;
};
node_status: string;
nodes_status: string;
global_param: PipelineGlobalParam[];
tensorBoardStatus?: TensorBoardStatus;


+ 23
- 1
react-ui/src/utils/index.ts View File

@@ -6,7 +6,6 @@

import { PageEnum } from '@/enums/pagesEnums';
import G6 from '@antv/g6';
import { number } from 'echarts';

/**
* 生成 8 位随机数
@@ -348,3 +347,26 @@ export const convertEmptyStringToUndefined = (value?: string): string | undefine
return value === '' ? undefined : value;
};

/**
* 获取工作流节点
*
* @param node_status - the status of the node
* @return the workflow node
*/
export const getWorkflowStatus = (node_status?: string | null) => {
if (!node_status) {
return;
}

const nodeStatusJson = parseJsonText(node_status);
if (!nodeStatusJson) {
return;
}

for (const key in nodeStatusJson) {
if (key.startsWith('workflow')) {
return nodeStatusJson[key];
}
}
return;
};

Loading…
Cancel
Save