diff --git a/src/components/seal-table/components/table-row.tsx b/src/components/seal-table/components/table-row.tsx index 13ae3664..234ad6a3 100644 --- a/src/components/seal-table/components/table-row.tsx +++ b/src/components/seal-table/components/table-row.tsx @@ -1,4 +1,6 @@ -import useSetChunkRequest from '@/hooks/use-chunk-request'; +import useSetChunkRequest, { + createAxiosToken +} from '@/hooks/use-chunk-request'; import useUpdateChunkedList from '@/hooks/use-update-chunk-list'; import { DownOutlined, RightOutlined } from '@ant-design/icons'; import { Button, Checkbox, Col, Empty, Row, Spin } from 'antd'; @@ -32,6 +34,7 @@ const TableRow: React.FC< } = props; const tableContext: any = React.useContext<{ allChildren?: any[]; + allSubChildren?: any[]; }>(TableContext); const { setChunkRequest } = useSetChunkRequest(); const [expanded, setExpanded] = useState(false); @@ -43,6 +46,7 @@ const TableRow: React.FC< const chunkRequestRef = useRef(null); const childrenDataRef = useRef([]); childrenDataRef.current = childrenData; + const axiosToken = useRef(null); const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({ dataList: childrenData, @@ -68,6 +72,7 @@ const TableRow: React.FC< clearInterval(pollTimer.current); } chunkRequestRef.current?.current?.cancel?.(); + axiosToken.current?.cancel?.(); }; }, []); @@ -88,8 +93,12 @@ const TableRow: React.FC< const handleLoadChildren = async () => { try { + axiosToken.current?.cancel?.(); + axiosToken.current = createAxiosToken(); setLoading(true); - const data = await loadChildren?.(record); + const data = await loadChildren?.(record, { + token: axiosToken.current?.token + }); setChildrenData(data || []); setLoading(false); @@ -144,6 +153,7 @@ const TableRow: React.FC< } if (expanded) { + axiosToken.current?.cancel?.(); return; } @@ -208,6 +218,10 @@ const TableRow: React.FC< }; }, [firstLoad, expanded, tableContext.allChildren]); + useEffect(() => { + console.log('allSubChildren===', tableContext.allSubChildren); + }, [tableContext.allSubChildren]); + const renderRowPrefix = () => { if (expandable && rowSelection) { return ( diff --git a/src/components/seal-table/types.ts b/src/components/seal-table/types.ts index 2fa87de8..e5d31722 100644 --- a/src/components/seal-table/types.ts +++ b/src/components/seal-table/types.ts @@ -53,7 +53,7 @@ export interface SealTableProps { onSort?: (dataIndex: string, order: 'ascend' | 'descend') => void; onExpand?: (expanded: boolean, record: any, rowKey: any) => void; renderChildren?: (data: any, parent?: any) => React.ReactNode; - loadChildren?: (record: any) => Promise; + loadChildren?: (record: any, options?: any) => Promise; loadChildrenAPI?: (record: any) => string; contentRendered?: () => void; rowKey: string; diff --git a/src/pages/llmodels/apis/index.ts b/src/pages/llmodels/apis/index.ts index 7cb1938c..c7671763 100644 --- a/src/pages/llmodels/apis/index.ts +++ b/src/pages/llmodels/apis/index.ts @@ -21,6 +21,16 @@ const setProxyUrl = (url: string) => { }; // ===================== Models ===================== + +export async function queryModelsInstances(options?: any) { + return request>( + MODEL_INSTANCE_API, + { + method: 'GET', + cancelToken: options?.token + } + ); +} export async function queryModelsList( params: Global.SearchParams, options?: any @@ -69,13 +79,15 @@ export async function queryModelDetail(id: number) { // ===================== Model Instances start ===================== export async function queryModelInstancesList( - params: Global.Pagination & { query?: string; id: number } + params: Global.Pagination & { query?: string; id: number }, + options?: any ) { return request>( `${MODELS_API}/${params.id}/instances`, { method: 'GET', - params + params, + cancelToken: options?.token } ); } diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx index dd70c1df..05a61a43 100644 --- a/src/pages/llmodels/components/table-list.tsx +++ b/src/pages/llmodels/components/table-list.tsx @@ -66,6 +66,7 @@ interface ModelsProps { handleCategoryChange: (val: any) => void; onViewLogs: () => void; onCancelViewLogs: () => void; + allInstances: ModelInstanceListItem[]; queryParams: { page: number; perPage: number; @@ -119,6 +120,7 @@ const Models: React.FC = ({ onViewLogs, onCancelViewLogs, handleCategoryChange, + allInstances, deleteIds, dataSource, gpuDeviceList, @@ -494,13 +496,15 @@ const Models: React.FC = ({ [deleteModelInstance] ); - const getModelInstances = async (row: any) => { + const getModelInstances = async (row: any, options?: any) => { const params = { id: row.id, page: 1, perPage: 100 }; - const data = await queryModelInstancesList(params); + const data = await queryModelInstancesList(params, { + token: options?.token + }); return data.items || []; }; @@ -668,9 +672,15 @@ const Models: React.FC = ({ const renderChildren = useCallback( (list: any, parent?: any) => { + let childList = list; + if (allInstances.length) { + childList = list.filter((item: any) => { + return allInstances.some((instance) => instance.id === item.id); + }); + } return ( = ({ > ); }, - [workerList] + [workerList, allInstances] ); const generateSource = useCallback((record: ListItem) => { diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index 54955a0f..7da281a1 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -1,5 +1,7 @@ import TableContext from '@/components/seal-table/table-context'; -import useSetChunkRequest from '@/hooks/use-chunk-request'; +import useSetChunkRequest, { + createAxiosToken as generateAxiosToken +} from '@/hooks/use-chunk-request'; import useUpdateChunkedList from '@/hooks/use-update-chunk-list'; import { queryWorkersList } from '@/pages/resources/apis'; import { @@ -9,10 +11,17 @@ import { import _ from 'lodash'; import qs from 'query-string'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; -import { MODELS_API, MODEL_INSTANCE_API, queryModelsList } from './apis'; +import { + MODELS_API, + MODEL_INSTANCE_API, + queryModelsInstances, + queryModelsList +} from './apis'; import TableList from './components/table-list'; import { ListItem } from './config/types'; +const INSTANCE_SYNC = 'instance_sync'; + const Models: React.FC = () => { const { setChunkRequest, createAxiosToken } = useSetChunkRequest(); const { setChunkRequest: setModelInstanceChunkRequest } = @@ -29,13 +38,14 @@ const Models: React.FC = () => { loading: false, total: 0 }); - const [pageHidden, setPageHidden] = useState(false); + + const [allInstances, setAllInstances] = useState([]); const [gpuDeviceList, setGpuDeviceList] = useState([]); const [workerList, setWorkerList] = useState([]); - const [firstLoad, setFirstLoad] = useState(true); const chunkRequedtRef = useRef(); const chunkInstanceRequedtRef = useRef(); const isPageHidden = useRef(false); + const instancesToken = useRef(); let axiosToken = createAxiosToken(); const [queryParams, setQueryParams] = useState({ page: 1, @@ -59,6 +69,21 @@ const Models: React.FC = () => { } }); + const fetchModelsInstances = async () => { + try { + instancesToken.current?.cancel?.(); + instancesToken.current = generateAxiosToken(); + const data: any = await queryModelsInstances({ + token: instancesToken.current?.token + }); + console.log('instance====', data); + setAllInstances(data.items || []); + } catch (error) { + // ignore + setAllInstances([]); + } + }; + const getWorkerList = async () => { try { const data = await queryWorkersList({ page: 1, perPage: 100 }); @@ -98,9 +123,6 @@ const Models: React.FC = () => { deletedIds: [] }); } - console.log('error+++', error); - } finally { - setFirstLoad(false); } }, [queryParams]); @@ -124,7 +146,7 @@ const Models: React.FC = () => { const updateInstanceHandler = (list: any) => { setModelInstances(list); window.postMessage( - { type: 'modelInstance', data: list }, + { type: INSTANCE_SYNC, data: list }, window.location.origin ); }; @@ -220,6 +242,7 @@ const Models: React.FC = () => { chunkRequedtRef.current?.current?.cancel?.(); cacheDataListRef.current = []; chunkInstanceRequedtRef.current?.current?.cancel?.(); + instancesToken.current?.cancel?.(); }; }, []); @@ -227,6 +250,7 @@ const Models: React.FC = () => { const handleVisibilityChange = async () => { if (document.visibilityState === 'visible') { isPageHidden.current = false; + await fetchModelsInstances(); await Promise.all([ createModelsChunkRequest(), createModelsInstanceChunkRequest() @@ -247,38 +271,6 @@ const Models: React.FC = () => { }; }, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]); - useEffect(() => { - const handleOnWindowMessage = (event: any) => { - const data = event.data; - console.log( - 'event.origin=======', - event.origin !== window.location.origin || - data.type !== 'modelInstance', - data, - event.origin, - window.location.origin - ); - - if ( - event.origin !== window.location.origin || - data.type !== 'modelInstance' - ) { - return; - } - - if (document.visibilityState === 'hidden') { - console.log('isPageHidden=======', document.visibilityState, data.data); - - setModelInstances(data.data); - } - }; - - window.addEventListener('message', handleOnWindowMessage); - return () => { - window.removeEventListener('message', handleOnWindowMessage); - }; - }, []); - return ( { handlePageChange={handlePageChange} handleDeleteSuccess={fetchData} onViewLogs={handleOnViewLogs} + allInstances={allInstances} onCancelViewLogs={handleOnCancelViewLogs} queryParams={queryParams} loading={dataSource.loading}