From 88aafbaf7b6e55de09ef2504551ad88a702568e6 Mon Sep 17 00:00:00 2001 From: jialin Date: Fri, 13 Feb 2026 16:10:10 +0800 Subject: [PATCH] refactor: list watch trigger --- src/hooks/use-table-fetch.ts | 97 ++++++++----------- src/hooks/use-update-chunk-list.ts | 12 +++ .../benchmark/components/left-actions.tsx | 18 ---- .../services/use-query-cluster-list.tsx | 19 ++-- src/pages/resources/components/gpus.tsx | 9 +- src/pages/resources/components/workers.tsx | 12 ++- 6 files changed, 79 insertions(+), 88 deletions(-) diff --git a/src/hooks/use-table-fetch.ts b/src/hooks/use-table-fetch.ts index c46902df..83a32241 100644 --- a/src/hooks/use-table-fetch.ts +++ b/src/hooks/use-table-fetch.ts @@ -1,4 +1,3 @@ -import { WatchEventType } from '@/config'; import { TABLE_SORT_DIRECTIONS } from '@/config/settings'; import useSetChunkRequest, { createAxiosToken @@ -65,12 +64,6 @@ export default function useTableFetch( const axiosTokenRef = useRef(null); const timerIDRef = useRef(null); - // ======= to resolve worker upate issue ======= - const shouldUpdateRef = useRef(false); - const loadendRef = useRef(false); - const currentWatchParamsRef = useRef(null); - // ============================================ - // for skeleton loading const [extraStatus, setExtraStatus] = useState>({ firstLoad: true @@ -97,23 +90,10 @@ export default function useTableFetch( ...defaultQueryParams }); + // for recognize the current watch trigger time, so that we can ignore the previous events + const triggerAtRef = useRef(0); + const { setChunkRequest } = useSetChunkRequest(); - const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({ - events: events, - dataList: dataSource.dataList, - setDataList(list, opts?: any) { - setDataSource((pre) => { - return { - total: pre.total, - totalPage: pre.totalPage, - loading: false, - loadend: true, - dataList: list, - deletedIds: opts?.deletedIds || [] - }; - }); - } - }); const debounceSetExtraStatus = _.debounce(setExtraStatus, 3000); @@ -132,16 +112,12 @@ export default function useTableFetch( const params = { ..._.pickBy(query || queryParams, (val: any) => !!val) }; - currentWatchParamsRef.current = { - query: { ...params } - }; + chunkRequestRef.current?.current?.cancel?.(); axiosTokenRef.current?.cancel?.('CANCEL_PREVIOUS_REQUEST'); axiosTokenRef.current = createAxiosToken(); const res = await fetchAPI(params, { token: axiosTokenRef.current?.token }); - shouldUpdateRef.current = false; - loadendRef.current = true; if (!dataSource.loadend) { // add a delay to avoid flash await new Promise((resolve) => { @@ -157,9 +133,6 @@ export default function useTableFetch( ...params, page: res.pagination.totalPage }; - currentWatchParamsRef.current = { - query: { ...newParams } - }; const newRes = await fetchAPI(newParams, { token: axiosTokenRef.current?.token }); @@ -177,7 +150,7 @@ export default function useTableFetch( if (isInfiniteScroll) { setQueryParams(newParams); } - return; + return true; } setDataSource({ @@ -195,6 +168,7 @@ export default function useTableFetch( ...query }); } + return true; } catch (error: any) { if (error.message !== 'CANCEL_PREVIOUS_REQUEST') { setDataSource({ @@ -205,9 +179,7 @@ export default function useTableFetch( totalPage: dataSource.totalPage }); } - - loadendRef.current = true; - shouldUpdateRef.current = false; + return false; } finally { debounceSetExtraStatus({ firstLoad: false @@ -216,32 +188,46 @@ export default function useTableFetch( }; // @ts-ignore - const debounceFetchData = _.debounce( - (params: any) => fetchData(params, true), - 300 - ); + const debounceFetchData = _.debounce(() => fetchData(), 300); + + const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({ + events: events, + dataList: dataSource.dataList, + triggerAt: updateManually ? triggerAtRef : undefined, + setDataList(list, opts?: any) { + setDataSource((pre) => { + return { + total: pre.total, + totalPage: pre.totalPage, + loading: false, + loadend: true, + dataList: list, + deletedIds: opts?.deletedIds || [] + }; + }); + }, + onCreate: (newItems: any) => { + // ======= to resolve worker update issue ======= + if (updateManually && triggerAtRef.current && newItems.length > 0) { + debounceFetchData(); + } + }, + onDelete: (newItems: any) => { + // ======= to resolve worker update issue ======= + if (updateManually && triggerAtRef.current && newItems.length > 0) { + debounceFetchData(); + } + } + }); const updateHandler = (list: any) => { _.each(list, (data: any) => { updateChunkedList(data); }); - shouldUpdateRef.current = list.some( - (data: any) => - data.type === WatchEventType.DELETE || - data.type === WatchEventType.CREATE - ); - - // ======= to resolve worker upate issue ======= - // when worker list change (create/delete), fetch data again to update the list - if (shouldUpdateRef.current && updateManually && loadendRef.current) { - debounceFetchData(currentWatchParamsRef.current || undefined); - } - // ============================================ }; const createTableListChunkRequest = async (params?: any) => { if (!API || !watch) return; - shouldUpdateRef.current = false; chunkRequestRef.current?.current?.cancel?.(); try { const currentParams = params || queryParams; @@ -252,6 +238,7 @@ export default function useTableFetch( url: `${API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`, handler: updateHandler }); + triggerAtRef.current = Date.now(); } catch (error) { // ignore } @@ -282,11 +269,10 @@ export default function useTableFetch( paginate?: boolean; } ) => { - loadendRef.current = false; const newQueryParams = { ...queryParams, ...params }; setQueryParams(newQueryParams); - await fetchData({ query: newQueryParams }); - if (watch && !options?.paginate) { + const res = await fetchData({ query: newQueryParams }); + if (watch && !options?.paginate && res) { createTableListChunkRequest(newQueryParams); } }; @@ -418,6 +404,7 @@ export default function useTableFetch( chunkRequestRef.current?.current?.cancel?.(); axiosTokenRef.current?.cancel?.(); cacheDataListRef.current = []; + triggerAtRef.current = 0; }; }, []); diff --git a/src/hooks/use-update-chunk-list.ts b/src/hooks/use-update-chunk-list.ts index fb3472dd..4b4902b7 100644 --- a/src/hooks/use-update-chunk-list.ts +++ b/src/hooks/use-update-chunk-list.ts @@ -98,8 +98,16 @@ export function useUpdateChunkedList(options: { // DELETE if (data?.type === WatchEventType.DELETE && events.includes('DELETE')) { + const deletedList: any[] = []; + cacheDataListRef.current = cacheDataListRef.current?.filter( (item: any) => { + // collect deleted items + if (triggerAt?.current) { + if (ids?.includes(item.id)) { + deletedList.push(item); + } + } return !ids?.includes(item.id); } ); @@ -107,6 +115,10 @@ export function useUpdateChunkedList(options: { options.setDataList?.([...cacheDataListRef.current], { deletedIds: [...deletedIdsRef.current] }); + + console.log('deletedList:', deletedList); + + options.onDelete?.(deletedList); } // UPDATE diff --git a/src/pages/benchmark/components/left-actions.tsx b/src/pages/benchmark/components/left-actions.tsx index a5699c53..bae09391 100644 --- a/src/pages/benchmark/components/left-actions.tsx +++ b/src/pages/benchmark/components/left-actions.tsx @@ -5,7 +5,6 @@ import { useIntl } from '@umijs/max'; import { Button, Input, Space } from 'antd'; import _ from 'lodash'; import React from 'react'; -import { profileOptions } from '../../benchmark/config'; export interface RightActionsProps { handleInputChange: (e: React.ChangeEvent) => void; @@ -82,23 +81,6 @@ const RightActions: React.FC = ({ }) } > - ({ - label: intl.formatMessage({ id: item.label }), - value: item.value - }))} - onChange={(value, option) => - handleQueryChange({ - profile: value, - page: 1 - }) - } - >