️ perf(driver-manager): 优化驱动状态缓存与加载协调

- 抽离驱动状态快照注册、恢复和请求收尾逻辑
- 避免过期请求覆盖最新目录状态或持续占用加载态
- 补充缓存恢复与请求竞态回归测试
This commit is contained in:
Syngnat
2026-08-01 14:50:09 +08:00
parent 4635d688c3
commit 2ecccae148
4 changed files with 210 additions and 83 deletions

View File

@@ -1,35 +1,91 @@
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
const source = readFileSync(
fileURLToPath(new globalThis.URL('./DriverManagerModal.tsx', import.meta.url)),
'utf8',
).replace(/\r\n/g, '\n');
import {
createDriverStatusSnapshotRegistry,
restoreDriverNetworkSnapshot,
restoreDriverStatusSnapshot,
settleLatestDriverRequest,
} from '../utils/driverManagerRequestState';
describe('DriverManagerModal request coordination boundary', () => {
it('lets the latest request clear a loading state even when it is a silent refresh', () => {
expect(source).toMatch(
/finally \{\s*if \(requestGeneration === statusRequestGenerationRef\.current\) \{\s*setLoading\(false\);/s,
);
expect(source).toMatch(
/finally \{\s*if \(requestGeneration === networkRequestGenerationRef\.current\) \{\s*setNetworkChecking\(false\);/s,
);
expect(source).not.toContain('showLoading && requestGeneration === statusRequestGenerationRef.current');
expect(source).not.toContain('showLoading && requestGeneration === networkRequestGenerationRef.current');
it('lets only the latest request clear loading, including silent refreshes', () => {
const setStatusLoading = vi.fn();
const setNetworkLoading = vi.fn();
expect(settleLatestDriverRequest(2, 3, setStatusLoading)).toBe(false);
expect(setStatusLoading).not.toHaveBeenCalled();
expect(settleLatestDriverRequest(3, 3, setStatusLoading)).toBe(true);
expect(setStatusLoading).toHaveBeenCalledWith(false);
expect(settleLatestDriverRequest(7, 7, setNetworkLoading)).toBe(true);
expect(setNetworkLoading).toHaveBeenCalledWith(false);
});
it('clears cold loading flags when another instance populated a fresh snapshot first', () => {
expect(source).toMatch(/if \(cachedStatus\) \{\s*setRows\(cachedStatus\.rows\);\s*setLoading\(false\);/s);
expect(source).toContain('downloadDirRef.current = cachedStatus.downloadDir;');
expect(source).toMatch(/if \(cachedNetwork\) \{\s*setNetworkStatus\(cachedNetwork\.status\);\s*setNetworkChecking\(false\);/s);
it('restores fresh snapshots and clears cold loading flags', () => {
const setRows = vi.fn();
const setStatusLoading = vi.fn();
const setDownloadDir = vi.fn();
const setNetworkStatus = vi.fn();
const setNetworkLoading = vi.fn();
const rows = [{ type: 'mysql' }];
const networkStatus = { reachable: true };
expect(restoreDriverStatusSnapshot({
rows,
downloadDir: 'D:/drivers',
cachedAt: 100,
intentSequence: 4,
}, {
setRows,
setLoading: setStatusLoading,
setDownloadDir,
})).toBe(true);
expect(setRows).toHaveBeenCalledWith(rows);
expect(setStatusLoading).toHaveBeenCalledWith(false);
expect(setDownloadDir).toHaveBeenCalledWith('D:/drivers');
expect(restoreDriverNetworkSnapshot({ status: networkStatus, cachedAt: 100 }, {
setStatus: setNetworkStatus,
setLoading: setNetworkLoading,
})).toBe(true);
expect(setNetworkStatus).toHaveBeenCalledWith(networkStatus);
expect(setNetworkLoading).toHaveBeenCalledWith(false);
});
it('keeps status snapshots keyed and rejects writes older than the latest intent for a directory', () => {
expect(source).toContain('const driverStatusSnapshotCache = new Map<string, DriverStatusSnapshot>();');
expect(source).toContain('const driverStatusSnapshotIntentByKey = new Map<string, number>();');
expect(source).toContain('preferredDriverStatusSnapshotKey = requestKey;');
expect(source).toContain('snapshot.intentSequence < latestIntentForKey');
expect(source).toContain('writeDriverStatusSnapshot(resolvedRequestKey, snapshot);');
it('keeps status snapshots keyed and rejects writes older than the latest intent', () => {
const snapshots = createDriverStatusSnapshotRegistry<{ type: string }>();
const mysqlKey = snapshots.beginRequest('D:/mysql', 2);
expect(snapshots.write(mysqlKey, {
rows: [{ type: 'stale' }],
downloadDir: 'D:/mysql',
cachedAt: 100,
intentSequence: 1,
})).toBe(false);
expect(snapshots.getPreferred()).toBeNull();
expect(snapshots.write(mysqlKey, {
rows: [{ type: 'mysql' }],
downloadDir: 'D:/mysql',
cachedAt: 200,
intentSequence: 2,
})).toBe(true);
expect(snapshots.getPreferred()?.rows).toEqual([{ type: 'mysql' }]);
const postgresKey = snapshots.beginRequest('D:/postgres', 3);
expect(snapshots.write(postgresKey, {
rows: [{ type: 'postgres' }],
downloadDir: 'D:/postgres',
cachedAt: 300,
intentSequence: 3,
})).toBe(true);
expect(snapshots.getPreferred()?.rows).toEqual([{ type: 'postgres' }]);
expect(snapshots.write(mysqlKey, {
rows: [{ type: 'older-mysql' }],
downloadDir: 'D:/mysql',
cachedAt: 150,
intentSequence: 1,
})).toBe(false);
});
});

View File

@@ -16,6 +16,14 @@ import {
getDriverLocalImportDirectoryHelp,
getDriverLocalImportSingleFileHelp,
} from '../utils/driverImportGuidance';
import {
createDriverStatusSnapshotRegistry,
normalizeDriverStatusRequestKey,
restoreDriverNetworkSnapshot,
restoreDriverStatusSnapshot,
settleLatestDriverRequest,
type DriverStatusSnapshot as DriverStatusSnapshotState,
} from '../utils/driverManagerRequestState';
import {
CheckDriverNetworkStatus,
DownloadDriverPackage,
@@ -469,16 +477,7 @@ const createDriverBatchProgress = (total: number, currentMessage: string): Drive
currentMessage,
});
type DriverStatusSnapshot = {
rows: DriverStatusRow[];
downloadDir: string;
cachedAt: number;
intentSequence: number;
};
const DEFAULT_DRIVER_STATUS_REQUEST_KEY = '<default>';
const driverStatusSnapshotCache = new Map<string, DriverStatusSnapshot>();
const driverStatusSnapshotIntentByKey = new Map<string, number>();
let preferredDriverStatusSnapshotKey = DEFAULT_DRIVER_STATUS_REQUEST_KEY;
const driverStatusSnapshots = createDriverStatusSnapshotRegistry<DriverStatusRow>();
let driverNetworkSnapshotCache: { status: DriverNetworkStatus; cachedAt: number } | null = null;
let driverStatusSnapshotIntentSequence = 0;
type DriverStatusBackendResult = Awaited<ReturnType<typeof GetDriverStatusList>>;
@@ -486,23 +485,6 @@ type DriverNetworkBackendResult = Awaited<ReturnType<typeof CheckDriverNetworkSt
const driverStatusInFlightRequests = new Map<string, Promise<DriverStatusBackendResult>>();
let driverNetworkInFlightRequest: Promise<DriverNetworkBackendResult> | null = null;
const normalizeDriverStatusRequestKey = (downloadDir: string): string => (
String(downloadDir || '').trim() || DEFAULT_DRIVER_STATUS_REQUEST_KEY
);
const getPreferredDriverStatusSnapshot = (): DriverStatusSnapshot | null => (
driverStatusSnapshotCache.get(preferredDriverStatusSnapshotKey) || null
);
const writeDriverStatusSnapshot = (requestKey: string, snapshot: DriverStatusSnapshot): void => {
const latestIntentForKey = driverStatusSnapshotIntentByKey.get(requestKey) || 0;
const cachedSnapshot = driverStatusSnapshotCache.get(requestKey);
if (snapshot.intentSequence < latestIntentForKey || snapshot.intentSequence < (cachedSnapshot?.intentSequence || 0)) {
return;
}
driverStatusSnapshotCache.set(requestKey, snapshot);
};
const requestDriverStatusShared = (downloadDir: string): Promise<DriverStatusBackendResult> => {
const requestKey = normalizeDriverStatusRequestKey(downloadDir);
const pendingRequest = driverStatusInFlightRequests.get(requestKey);
@@ -601,12 +583,12 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
() => buildDriverManagerWorkbenchTheme(darkMode, opacity),
[darkMode, opacity, appearance.uiVersion],
);
const [loading, setLoading] = useState(() => open && !getPreferredDriverStatusSnapshot());
const [downloadDir, setDownloadDir] = useState(() => getPreferredDriverStatusSnapshot()?.downloadDir || '');
const [loading, setLoading] = useState(() => open && !driverStatusSnapshots.getPreferred());
const [downloadDir, setDownloadDir] = useState(() => driverStatusSnapshots.getPreferred()?.downloadDir || '');
const [networkChecking, setNetworkChecking] = useState(() => open && !driverNetworkSnapshotCache);
const [networkStatus, setNetworkStatus] = useState<DriverNetworkStatus | null>(() => driverNetworkSnapshotCache?.status || null);
const [searchKeyword, setSearchKeyword] = useState('');
const [rows, setRows] = useState<DriverStatusRow[]>(() => getPreferredDriverStatusSnapshot()?.rows || []);
const [rows, setRows] = useState<DriverStatusRow[]>(() => driverStatusSnapshots.getPreferred()?.rows || []);
const [actionState, setActionState] = useState<{ driverType: string; kind: DriverActionKind }>({ driverType: '', kind: '' });
const [batchAction, setBatchAction] = useState<DriverBatchActionKind>('');
const [batchProgress, setBatchProgress] = useState<DriverBatchProgressState | null>(null);
@@ -762,9 +744,7 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
const snapshotIntentSequence = driverStatusSnapshotIntentSequence + 1;
driverStatusSnapshotIntentSequence = snapshotIntentSequence;
const requestedDownloadDir = downloadDirRef.current;
const requestKey = normalizeDriverStatusRequestKey(requestedDownloadDir);
preferredDriverStatusSnapshotKey = requestKey;
driverStatusSnapshotIntentByKey.set(requestKey, snapshotIntentSequence);
const requestKey = driverStatusSnapshots.beginRequest(requestedDownloadDir, snapshotIntentSequence);
const showLoading = options?.showLoading ?? true;
if (showLoading) {
setLoading(true);
@@ -816,25 +796,23 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
message: String(item.message || '').trim() || undefined,
}));
setRows(nextRows);
const snapshot: DriverStatusSnapshot = {
const snapshot: DriverStatusSnapshotState<DriverStatusRow> = {
rows: nextRows,
downloadDir: effectiveDownloadDir,
cachedAt: Date.now(),
intentSequence: snapshotIntentSequence,
};
writeDriverStatusSnapshot(requestKey, snapshot);
driverStatusSnapshots.write(requestKey, snapshot);
const resolvedRequestKey = normalizeDriverStatusRequestKey(effectiveDownloadDir);
if (resolvedRequestKey !== requestKey) {
writeDriverStatusSnapshot(resolvedRequestKey, snapshot);
driverStatusSnapshots.write(resolvedRequestKey, snapshot);
}
} catch (err: any) {
if (requestGeneration === statusRequestGenerationRef.current && toastOnError) {
message.error(t('driver.modal.error.statusFetchWithDetail', { detail: err?.message || String(err) }));
}
} finally {
if (requestGeneration === statusRequestGenerationRef.current) {
setLoading(false);
}
settleLatestDriverRequest(requestGeneration, statusRequestGenerationRef.current, setLoading);
}
}, [resolveDriverErrorMessage]);
@@ -901,9 +879,7 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
message.error(t('driver.modal.error.networkCheckWithDetail', { detail: err?.message || String(err) }));
}
} finally {
if (requestGeneration === networkRequestGenerationRef.current) {
setNetworkChecking(false);
}
settleLatestDriverRequest(requestGeneration, networkRequestGenerationRef.current, setNetworkChecking);
}
}, [resolveDriverErrorMessage]);
@@ -1061,16 +1037,16 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
return;
}
const cachedStatus = getPreferredDriverStatusSnapshot();
const cachedStatus = driverStatusSnapshots.getPreferred();
const hasCachedStatus = !!cachedStatus;
if (cachedStatus) {
setRows(cachedStatus.rows);
setLoading(false);
if (cachedStatus.downloadDir) {
downloadDirRef.current = cachedStatus.downloadDir;
setDownloadDir(cachedStatus.downloadDir);
}
}
restoreDriverStatusSnapshot(cachedStatus, {
setRows,
setLoading,
setDownloadDir: (nextDownloadDir) => {
downloadDirRef.current = nextDownloadDir;
setDownloadDir(nextDownloadDir);
},
});
const shouldRefreshStatus = !cachedStatus || !isFreshCache(cachedStatus.cachedAt, DRIVER_STATUS_CACHE_TTL_MS);
if (shouldRefreshStatus) {
void refreshStatus(false, { showLoading: !hasCachedStatus });
@@ -1078,10 +1054,10 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
const cachedNetwork = driverNetworkSnapshotCache;
const hasCachedNetwork = !!cachedNetwork;
if (cachedNetwork) {
setNetworkStatus(cachedNetwork.status);
setNetworkChecking(false);
}
restoreDriverNetworkSnapshot(cachedNetwork, {
setStatus: setNetworkStatus,
setLoading: setNetworkChecking,
});
const shouldRefreshNetwork = !cachedNetwork || !isFreshCache(cachedNetwork.cachedAt, DRIVER_NETWORK_CACHE_TTL_MS);
if (shouldRefreshNetwork) {
void checkNetworkStatus(false, { showLoading: !hasCachedNetwork });

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import { resolveDriverErrorMessageText } from '../components/DriverManagerModal';
import { t as catalogT } from '../i18n/catalog';
import { t } from '../i18n';
import {
@@ -68,8 +69,6 @@ describe('driver import guidance', () => {
backendWrapperKeys,
expected,
}) => {
const { resolveDriverErrorMessageText } = await import('../components/DriverManagerModal');
expect(resolveDriverErrorMessageText(
rawMessage,
fallbackMessage,

View File

@@ -0,0 +1,96 @@
export type DriverStatusSnapshot<TRow> = {
rows: TRow[];
downloadDir: string;
cachedAt: number;
intentSequence: number;
};
export type DriverNetworkSnapshot<TStatus> = {
status: TStatus;
cachedAt: number;
};
const DEFAULT_DRIVER_STATUS_REQUEST_KEY = '<default>';
export const normalizeDriverStatusRequestKey = (downloadDir: string): string => (
String(downloadDir || '').trim() || DEFAULT_DRIVER_STATUS_REQUEST_KEY
);
export const createDriverStatusSnapshotRegistry = <TRow>() => {
const snapshots = new Map<string, DriverStatusSnapshot<TRow>>();
const latestIntentByKey = new Map<string, number>();
let preferredRequestKey = DEFAULT_DRIVER_STATUS_REQUEST_KEY;
return {
beginRequest(downloadDir: string, intentSequence: number): string {
const requestKey = normalizeDriverStatusRequestKey(downloadDir);
preferredRequestKey = requestKey;
latestIntentByKey.set(requestKey, intentSequence);
return requestKey;
},
getPreferred(): DriverStatusSnapshot<TRow> | null {
return snapshots.get(preferredRequestKey) || null;
},
write(requestKey: string, snapshot: DriverStatusSnapshot<TRow>): boolean {
const normalizedRequestKey = normalizeDriverStatusRequestKey(requestKey);
const latestIntentForKey = latestIntentByKey.get(normalizedRequestKey) || 0;
const cachedSnapshot = snapshots.get(normalizedRequestKey);
if (
snapshot.intentSequence < latestIntentForKey
|| snapshot.intentSequence < (cachedSnapshot?.intentSequence || 0)
) {
return false;
}
snapshots.set(normalizedRequestKey, snapshot);
return true;
},
};
};
export const settleLatestDriverRequest = (
requestGeneration: number,
latestRequestGeneration: number,
setLoading: (loading: boolean) => void,
): boolean => {
if (requestGeneration !== latestRequestGeneration) {
return false;
}
setLoading(false);
return true;
};
export const restoreDriverStatusSnapshot = <TRow>(
snapshot: DriverStatusSnapshot<TRow> | null,
callbacks: {
setRows: (rows: TRow[]) => void;
setLoading: (loading: boolean) => void;
setDownloadDir: (downloadDir: string) => void;
},
): boolean => {
if (!snapshot) {
return false;
}
callbacks.setRows(snapshot.rows);
callbacks.setLoading(false);
if (snapshot.downloadDir) {
callbacks.setDownloadDir(snapshot.downloadDir);
}
return true;
};
export const restoreDriverNetworkSnapshot = <TStatus>(
snapshot: DriverNetworkSnapshot<TStatus> | null,
callbacks: {
setStatus: (status: TStatus) => void;
setLoading: (loading: boolean) => void;
},
): boolean => {
if (!snapshot) {
return false;
}
callbacks.setStatus(snapshot.status);
callbacks.setLoading(false);
return true;
};