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