perf: cancel the request when leaving page

This commit is contained in:
jialin
2026-01-16 16:53:38 +08:00
parent 3e359a69c7
commit b4f69a4e2e
6 changed files with 60 additions and 44 deletions
+18 -9
View File
@@ -58,11 +58,12 @@ export default function useTableFetch<T>(
updateManually
} = options;
const pollingRef = useRef<any>(null);
const chunkRequedtRef = useRef<any>(null);
const chunkRequestRef = useRef<any>(null);
const modalRef = useRef<any>(null);
const rowSelection = useTableRowSelection();
const { sortOrder, handleMultiSortChange } = useTableMultiSort();
const axiosTokenRef = useRef<any>(null);
const timerIDRef = useRef<any>(null);
// ======= to resolve worker upate issue =======
const shouldUpdateRef = useRef(false);
@@ -238,16 +239,16 @@ export default function useTableFetch<T>(
// ============================================
};
const createModelsChunkRequest = async (params?: any) => {
const createTableListChunkRequest = async (params?: any) => {
if (!API || !watch) return;
shouldUpdateRef.current = false;
chunkRequedtRef.current?.current?.cancel?.();
chunkRequestRef.current?.current?.cancel?.();
try {
const currentParams = params || queryParams;
const query = _.omit(currentParams, ['page', 'perPage']);
chunkRequedtRef.current = setChunkRequest({
chunkRequestRef.current = setChunkRequest({
url: `${API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`,
handler: updateHandler
});
@@ -286,7 +287,7 @@ export default function useTableFetch<T>(
setQueryParams(newQueryParams);
await fetchData({ query: newQueryParams });
if (watch && !options?.paginate) {
createModelsChunkRequest(newQueryParams);
createTableListChunkRequest(newQueryParams);
}
};
@@ -338,7 +339,6 @@ export default function useTableFetch<T>(
name: row.name,
...options,
async onOk() {
console.log('OK');
await deleteAPI?.(row.id, {
...modalRef.current?.configuration
});
@@ -398,15 +398,24 @@ export default function useTableFetch<T>(
}, [dataSource.loadend, queryParams]);
useEffect(() => {
let mounted = true;
const init = async () => {
await fetchData();
setTimeout(() => {
createModelsChunkRequest();
timerIDRef.current = setTimeout(() => {
if (mounted) {
createTableListChunkRequest();
}
}, 200);
};
init();
return () => {
chunkRequedtRef.current?.cancel?.();
mounted = false;
clearTimeout(timerIDRef.current);
chunkRequestRef.current?.current?.cancel?.();
axiosTokenRef.current?.cancel?.();
cacheDataListRef.current = [];
};
+8 -2
View File
@@ -156,9 +156,15 @@ export async function queryClusterItem(params: { id: number }, options?: any) {
});
}
export async function queryClusterToken(params: { id: number }) {
export async function queryClusterToken(
params: { id: number },
options?: {
token?: any;
}
) {
return request(`${CLUSTERS_API}/${params.id}/${CLUSTER_TOKEN}`, {
method: 'GET'
method: 'GET',
cancelToken: options?.token
});
}
@@ -1,4 +1,5 @@
import GSDrawer from '@/components/scroller-modal/gs-drawer';
import { createAxiosToken } from '@/hooks/use-chunk-request';
import ColumnWrapper from '@/pages/_components/column-wrapper';
import useAddWorkerMessage from '@/pages/cluster-management/hooks/use-add-worker-message';
import { useIntl } from '@umijs/max';
@@ -59,8 +60,10 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
stepList = []
} = props || {};
const intl = useIntl();
const { addedCount, createModelsChunkRequest } = useAddWorkerMessage();
const { addedCount, createModelsChunkRequest, chunkRequestRef } =
useAddWorkerMessage();
const firstLoad = React.useRef(true);
const axiosTokenRef = React.useRef<any>(null);
const [registrationInfo, setRegistrationInfo] = React.useState<{
token: string;
image: string;
@@ -75,7 +78,12 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
const handleOnClusterChange = async (value: number, row?: any) => {
try {
const data = await queryClusterToken({ id: value });
axiosTokenRef.current?.cancel?.();
axiosTokenRef.current = createAxiosToken();
const data = await queryClusterToken(
{ id: value },
{ token: axiosTokenRef.current.token }
);
firstLoad.current = false;
setRegistrationInfo({
...data,
@@ -92,12 +100,17 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
}
return () => {
firstLoad.current = true;
chunkRequestRef.current?.current?.cancel?.();
axiosTokenRef.current?.cancel?.();
};
}, [open, cluster_id]);
useEffect(() => {
if (open) {
createModelsChunkRequest();
} else {
chunkRequestRef.current?.current?.cancel?.();
axiosTokenRef.current?.cancel?.();
}
}, [open]);
@@ -1,7 +1,7 @@
import BaseSelect from '@/components/seal-form/base/select';
import { useIntl } from '@umijs/max';
import { Spin, Typography } from 'antd';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useAddWorkerContext } from './add-worker-context';
import { AddWorkerStepProps, StepNamesMap } from './config';
import { Title } from './constainers';
@@ -20,10 +20,17 @@ const SelectCluster: React.FC<AddWorkerStepProps> = ({ disabled }) => {
} = useAddWorkerContext();
const intl = useIntl();
const clusterId = summary.get('cluster_id');
const [clusterId, setClusterId] = useState<number | null>(
summary.get('cluster_id')
);
const stepIndex = stepList.indexOf(StepNamesMap.SelectCluster) + 1;
const handleOnClusterChange = (value: number, option: any) => {
setClusterId(value);
onClusterChange?.(value, option);
};
useEffect(() => {
const unregister = registerField('cluster_id');
return () => {
@@ -34,6 +41,7 @@ const SelectCluster: React.FC<AddWorkerStepProps> = ({ disabled }) => {
useEffect(() => {
updateField('cluster_id', registrationInfo.cluster_id);
// update cluster name in summary
setClusterId(registrationInfo.cluster_id);
const selectedCluster = clusterList?.find(
(item) => item.value === registrationInfo.cluster_id
);
@@ -76,7 +84,7 @@ const SelectCluster: React.FC<AddWorkerStepProps> = ({ disabled }) => {
defaultValue={registrationInfo.cluster_id}
options={clusterList}
value={clusterId}
onChange={onClusterChange}
onChange={handleOnClusterChange}
style={{ width: '100%' }}
/>
{!clusterLoading && !clusterList?.length && (
@@ -64,6 +64,7 @@ export default function useAddWorkerMessage() {
return {
addedCount,
chunkRequestRef,
createModelsChunkRequest
};
}
+7 -28
View File
@@ -240,6 +240,7 @@ export const useCheckCompatibility = () => {
message: ''
};
}
const {
compatible,
compatibility_messages = [],
@@ -263,13 +264,10 @@ export const useCheckCompatibility = () => {
Object.entries(resource_claim_by_cluster_id || {})
);
// current cluster resource claim
// current cluster resource claim: {ram: number, vram: number}
const resource_claim = resourceClaimMap.get(`${cluster_id}`);
const hasClaim = !!resource_claim?.ram || !!resource_claim?.vram;
// current cluster is not available, but other clusters are available
const othersAvailable = !hasClaim && resourceClaimMap.size > 0;
const hasClaim = resourceClaimMap.has(`${cluster_id}`);
let compatibilityMessage = compatibility_messages.join(' ');
@@ -288,8 +286,8 @@ export const useCheckCompatibility = () => {
};
if (hasClaim) {
const ram = convertFileSize(resource_claim.ram, 2);
const vram = convertFileSize(resource_claim.vram, 2);
const ram = convertFileSize(resource_claim?.ram || 0, 2);
const vram = convertFileSize(resource_claim?.vram || 0, 2);
let messageId = 'models.form.check.claims';
if (!ram) {
messageId = 'models.form.check.claims2';
@@ -301,30 +299,11 @@ export const useCheckCompatibility = () => {
title: intl.formatMessage({ id: 'models.form.check.passed' }),
message: intl.formatMessage({ id: messageId }, { ram, vram })
};
} else if (
othersAvailable &&
!scheduling_messages?.length &&
!compatibility_messages?.length
) {
// no specific messages, but other clusters are available
msgData = {
title: intl.formatMessage({
id: 'models.form.check.clusterUnavailable'
}),
message: intl.formatMessage(
{
id: 'models.form.check.otherClustersAvailable'
},
{
clusters: getAvailableClusters(Array.from(resourceClaimMap.keys()))
}
)
};
}
return {
show: !compatible || hasClaim || othersAvailable,
type: !compatible || othersAvailable ? 'warning' : 'success',
show: !compatible || hasClaim,
type: !compatible ? 'warning' : 'success',
...msgData
};
};