fix(trace): extract trace utility functions to separate module

Move mergeTraceModals, updatePercentAndStart and findNodeById functions from trace page component to a dedicated utils module to fix react-hooks error
This commit is contained in:
icarus 2025-10-14 17:00:20 +08:00
parent 2e694a87f8
commit 94c112c066
2 changed files with 48 additions and 46 deletions

View File

@ -6,6 +6,7 @@ import { Divider } from 'antd/lib'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { findNodeById, mergeTraceModals, updatePercentAndStart } from '../utils'
import { Box, GridItem, SimpleGrid, Text, VStack } from './Component'
import SpanDetail from './SpanDetail'
import TraceTree from './TraceTree'
@ -24,39 +25,6 @@ export const TracePage: React.FC<TracePageProp> = ({ topicId, traceId, modelName
const intervalRef = useRef<NodeJS.Timeout | null>(null)
const { t } = useTranslation()
const mergeTraceModals = useCallback((oldNodes: TraceModal[], newNodes: TraceModal[]): TraceModal[] => {
const oldMap = new Map(oldNodes.map((n) => [n.id, n]))
return newNodes.map((newNode) => {
const oldNode = oldMap.get(newNode.id)
if (oldNode) {
// 如果旧节点已经结束,则直接返回旧节点
if (oldNode.endTime) {
return oldNode
}
oldNode.children = mergeTraceModals(oldNode.children, newNode.children)
Object.assign(oldNode, newNode)
return oldNode
} else {
return newNode
}
})
}, [])
const updatePercentAndStart = useCallback((nodes: TraceModal[], rootStart?: number, rootEnd?: number) => {
nodes.forEach((node) => {
const _rootStart = rootStart || node.startTime
const _rootEnd = rootEnd || node.endTime || Date.now()
const endTime = node.endTime || _rootEnd
const usedTime = endTime - node.startTime
const duration = _rootEnd - _rootStart
node.start = ((node.startTime - _rootStart) * 100) / duration
node.percent = duration === 0 ? 0 : (usedTime * 100) / duration
if (node.children) {
updatePercentAndStart(node.children, _rootStart, _rootEnd)
}
})
}, [])
const getRootSpan = (spans: SpanEntity[]): TraceModal[] => {
const map: Map<string, TraceModal> = new Map()
@ -78,17 +46,6 @@ export const TracePage: React.FC<TracePageProp> = ({ topicId, traceId, modelName
)
}
const findNodeById = useCallback((nodes: TraceModal[], id: string): TraceModal | null => {
for (const n of nodes) {
if (n.id === id) return n
if (n.children) {
const found = findNodeById(n.children, id)
if (found) return found
}
}
return null
}, [])
const getTraceData = useCallback(async (): Promise<boolean> => {
const datas = topicId && traceId ? await window.api.trace.getData(topicId, traceId, modelName) : []
const matchedSpans = getRootSpan(datas)
@ -96,7 +53,7 @@ export const TracePage: React.FC<TracePageProp> = ({ topicId, traceId, modelName
setSpans((prev) => mergeTraceModals(prev, matchedSpans))
const isEnded = !matchedSpans.find((e) => !e.endTime || e.endTime <= 0)
return isEnded
}, [topicId, traceId, modelName, updatePercentAndStart, mergeTraceModals])
}, [topicId, traceId, modelName])
const handleNodeClick = (nodeId: string) => {
const latestNode = findNodeById(spans, nodeId)
@ -148,7 +105,7 @@ export const TracePage: React.FC<TracePageProp> = ({ topicId, traceId, modelName
setSelectNode(latest)
}
}
}, [spans, selectNode, findNodeById])
}, [spans, selectNode])
return (
<div className="trace-window">

View File

@ -0,0 +1,45 @@
import { TraceModal } from '../pages/TraceModel'
export const updatePercentAndStart = (nodes: TraceModal[], rootStart?: number, rootEnd?: number) => {
nodes.forEach((node) => {
const _rootStart = rootStart || node.startTime
const _rootEnd = rootEnd || node.endTime || Date.now()
const endTime = node.endTime || _rootEnd
const usedTime = endTime - node.startTime
const duration = _rootEnd - _rootStart
node.start = ((node.startTime - _rootStart) * 100) / duration
node.percent = duration === 0 ? 0 : (usedTime * 100) / duration
if (node.children) {
updatePercentAndStart(node.children, _rootStart, _rootEnd)
}
})
}
export const findNodeById = (nodes: TraceModal[], id: string): TraceModal | null => {
for (const n of nodes) {
if (n.id === id) return n
if (n.children) {
const found = findNodeById(n.children, id)
if (found) return found
}
}
return null
}
export const mergeTraceModals = (oldNodes: TraceModal[], newNodes: TraceModal[]): TraceModal[] => {
const oldMap = new Map(oldNodes.map((n) => [n.id, n]))
return newNodes.map((newNode) => {
const oldNode = oldMap.get(newNode.id)
if (oldNode) {
// 如果旧节点已经结束,则直接返回旧节点
if (oldNode.endTime) {
return oldNode
}
oldNode.children = mergeTraceModals(oldNode.children, newNode.children)
Object.assign(oldNode, newNode)
return oldNode
} else {
return newNode
}
})
}