|
|
|
@@ -28,6 +28,7 @@ function ExperimentText() { |
|
|
|
const [propsDrawerOpen, openPropsDrawer, closePropsDrawer, propsDrawerOpenRef] = |
|
|
|
useVisible(false); |
|
|
|
const navigate = useNavigate(); |
|
|
|
const evtSourceRef = useRef(); |
|
|
|
const width = 110; |
|
|
|
const height = 36; |
|
|
|
|
|
|
|
@@ -48,6 +49,9 @@ function ExperimentText() { |
|
|
|
if (timerRef.current) { |
|
|
|
clearTimeout(timerRef.current); |
|
|
|
} |
|
|
|
if (evtSourceRef.current) { |
|
|
|
evtSourceRef.current.close(); |
|
|
|
} |
|
|
|
}; |
|
|
|
}, []); |
|
|
|
|
|
|
|
@@ -68,7 +72,7 @@ function ExperimentText() { |
|
|
|
item.imgName = item.img.slice(0, item.img.length - 4); |
|
|
|
}); |
|
|
|
workflowRef.current = dag; |
|
|
|
getExperimentInstance(true); |
|
|
|
getExperimentInstance(); |
|
|
|
} catch (error) { |
|
|
|
// JSON.parse 错误 |
|
|
|
console.log(error); |
|
|
|
@@ -77,50 +81,30 @@ function ExperimentText() { |
|
|
|
}; |
|
|
|
|
|
|
|
// 获取实验实例 |
|
|
|
const getExperimentInstance = async (first) => { |
|
|
|
const getExperimentInstance = async () => { |
|
|
|
const [res] = await to(getExperimentIns(locationParams.id)); |
|
|
|
if (res && res.data && workflowRef.current) { |
|
|
|
setExperimentIns(res.data); |
|
|
|
const { status, nodes_status } = res.data; |
|
|
|
const { status, nodes_status, argo_ins_ns, argo_ins_name } = res.data; |
|
|
|
const workflowData = workflowRef.current; |
|
|
|
const experimentStatusObjs = JSON.parse(nodes_status); |
|
|
|
workflowData.nodes.forEach((item) => { |
|
|
|
const experimentNode = experimentStatusObjs?.[item.id] ?? {}; |
|
|
|
const { finishedAt, startedAt, phase, id } = experimentNode; |
|
|
|
item.experimentStartTime = startedAt; |
|
|
|
item.experimentEndTime = finishedAt; |
|
|
|
item.experimentStatus = phase; |
|
|
|
item.workflowId = id; |
|
|
|
item.img = phase ? `${item.imgName}-${phase}.png` : `${item.imgName}.png`; |
|
|
|
const experimentNode = experimentStatusObjs?.[item.id]; |
|
|
|
updateWorkflowNode(item, experimentNode); |
|
|
|
}); |
|
|
|
|
|
|
|
// 更新打开的抽屉数据 |
|
|
|
if (propsDrawerOpenRef.current && experimentNodeDataRef.current) { |
|
|
|
const currentId = experimentNodeDataRef.current.id; |
|
|
|
const node = workflowData.nodes.find((item) => item.id === currentId); |
|
|
|
if (node) { |
|
|
|
setExperimentNodeData(node); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
getGraphData(workflowData, first); |
|
|
|
|
|
|
|
// 运行中或者等待中,每5秒获取一次实验实例 |
|
|
|
if (status === ExperimentStatus.Pending || status === ExperimentStatus.Running) { |
|
|
|
timerRef.current = setTimeout(() => { |
|
|
|
getExperimentInstance(false); |
|
|
|
}, 5 * 1000); |
|
|
|
} |
|
|
|
// 绘制图 |
|
|
|
getGraphData(workflowData, true); |
|
|
|
|
|
|
|
// 如果状态是 Pending, 打开第一个节点 |
|
|
|
// 如果状态是 Running,打开第一个运行中的节点,如果没有运行中的节点,打开第一个节点 |
|
|
|
if (first && status === ExperimentStatus.Pending) { |
|
|
|
if (status === ExperimentStatus.Pending) { |
|
|
|
const node = workflowData.nodes[0]; |
|
|
|
if (node) { |
|
|
|
setExperimentNodeData(node); |
|
|
|
openPropsDrawer(); |
|
|
|
} |
|
|
|
} else if (first && status === ExperimentStatus.Running) { |
|
|
|
} else if (status === ExperimentStatus.Running) { |
|
|
|
const node = |
|
|
|
workflowData.nodes.find((item) => item.experimentStatus === ExperimentStatus.Running) ?? |
|
|
|
workflowData.nodes[0]; |
|
|
|
@@ -129,9 +113,81 @@ function ExperimentText() { |
|
|
|
openPropsDrawer(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 运行中或者等待中,开启 SSE |
|
|
|
if (status === ExperimentStatus.Pending || status === ExperimentStatus.Running) { |
|
|
|
setupSSE(argo_ins_name, argo_ins_ns); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const setupSSE = (name, namespace) => { |
|
|
|
const { origin } = location; |
|
|
|
const evtSource = new EventSource( |
|
|
|
`${origin}/api/v1/realtimeStatus?listOptions.fieldSelector=metadata.namespace%3D${namespace}%2Cmetadata.name%3D${name}`, |
|
|
|
{ withCredentials: true }, |
|
|
|
); |
|
|
|
evtSource.onmessage = (event) => { |
|
|
|
const data = event?.data; |
|
|
|
if (!data) { |
|
|
|
return; |
|
|
|
} |
|
|
|
try { |
|
|
|
const dataJson = JSON.parse(data); |
|
|
|
const statusData = dataJson?.result?.object?.status; |
|
|
|
if (!statusData) { |
|
|
|
return; |
|
|
|
} |
|
|
|
const { startedAt, finishedAt, phase, nodes = {} } = statusData; |
|
|
|
setExperimentIns((prev) => ({ |
|
|
|
...prev, |
|
|
|
finish_time: finishedAt, |
|
|
|
status: phase, |
|
|
|
})); |
|
|
|
|
|
|
|
const workflowData = workflowRef.current; |
|
|
|
workflowData.nodes.forEach((item) => { |
|
|
|
const experimentNode = Object.values(nodes).find((node) => node.displayName === item.id); |
|
|
|
updateWorkflowNode(item, experimentNode); |
|
|
|
}); |
|
|
|
getGraphData(workflowData, false); |
|
|
|
|
|
|
|
// 更新打开的抽屉数据 |
|
|
|
if (propsDrawerOpenRef.current && experimentNodeDataRef.current) { |
|
|
|
const currentId = experimentNodeDataRef.current.id; |
|
|
|
const node = workflowData.nodes.find((item) => item.id === currentId); |
|
|
|
if (node) { |
|
|
|
setExperimentNodeData(node); |
|
|
|
} |
|
|
|
} |
|
|
|
if (phase !== ExperimentStatus.Pending && phase !== ExperimentStatus.Running) { |
|
|
|
evtSource.close(); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.log(error); |
|
|
|
} |
|
|
|
}; |
|
|
|
evtSource.onerror = (error) => { |
|
|
|
console.log('sse error', error); |
|
|
|
}; |
|
|
|
|
|
|
|
evtSourceRef.current = evtSource; |
|
|
|
}; |
|
|
|
|
|
|
|
function updateWorkflowNode(workflowNode, statusNode) { |
|
|
|
if (!statusNode) { |
|
|
|
return; |
|
|
|
} |
|
|
|
const { finishedAt, startedAt, phase, id } = statusNode; |
|
|
|
workflowNode.experimentStartTime = startedAt; |
|
|
|
workflowNode.experimentEndTime = finishedAt; |
|
|
|
workflowNode.experimentStatus = phase; |
|
|
|
workflowNode.workflowId = id; |
|
|
|
workflowNode.img = phase |
|
|
|
? `${workflowNode.imgName}-${phase}.png` |
|
|
|
: `${workflowNode.imgName}.png`; |
|
|
|
} |
|
|
|
|
|
|
|
// 根据数据,渲染图 |
|
|
|
const getGraphData = (data, first) => { |
|
|
|
if (graph) { |
|
|
|
@@ -151,7 +207,7 @@ function ExperimentText() { |
|
|
|
} |
|
|
|
} else { |
|
|
|
setTimeout(() => { |
|
|
|
getGraphData(data); |
|
|
|
getGraphData(data, first); |
|
|
|
}, 500); |
|
|
|
} |
|
|
|
}; |
|
|
|
|