mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-10 23:11:40 +08:00
🐛 fix(connection): 修复失败连接高频重试并暂停后台自动元数据拉取 #331
- 后端为失败数据库连接增加冷却窗口,避免短时间内重复真实建连 - 补充失败冷却回归测试,覆盖重复失败、冷却后重试和成功后清理场景 - 前端在后台态暂停查询页、侧边栏和表概览的自动元数据拉取 - 保持手动刷新、手动展开等显式操作行为不变
This commit is contained in:
22
frontend/src/utils/autoFetchVisibility.test.ts
Normal file
22
frontend/src/utils/autoFetchVisibility.test.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { isAutoFetchVisible } from './autoFetchVisibility';
|
||||
|
||||
describe('isAutoFetchVisible', () => {
|
||||
it('allows auto fetch only when the document is visible and not hidden', () => {
|
||||
expect(isAutoFetchVisible({ hidden: false, visibilityState: 'visible' })).toBe(true);
|
||||
});
|
||||
|
||||
it('blocks auto fetch when the page is hidden even if visibilityState looks visible', () => {
|
||||
expect(isAutoFetchVisible({ hidden: true, visibilityState: 'visible' })).toBe(false);
|
||||
});
|
||||
|
||||
it('blocks auto fetch when visibilityState is not visible', () => {
|
||||
expect(isAutoFetchVisible({ hidden: false, visibilityState: 'hidden' })).toBe(false);
|
||||
});
|
||||
|
||||
it('defaults to allowing auto fetch when document visibility APIs are unavailable', () => {
|
||||
expect(isAutoFetchVisible(undefined)).toBe(true);
|
||||
expect(isAutoFetchVisible({})).toBe(true);
|
||||
});
|
||||
});
|
||||
54
frontend/src/utils/autoFetchVisibility.ts
Normal file
54
frontend/src/utils/autoFetchVisibility.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
type AutoFetchVisibilitySource = Partial<Pick<Document, 'hidden' | 'visibilityState'>> | undefined;
|
||||
|
||||
export const isAutoFetchVisible = (source?: AutoFetchVisibilitySource): boolean => {
|
||||
if (!source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (source.hidden === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source.visibilityState && source.visibilityState !== 'visible') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const getDocumentAutoFetchVisibility = (): boolean => {
|
||||
if (typeof document === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isAutoFetchVisible(document);
|
||||
};
|
||||
|
||||
export const useAutoFetchVisibility = (): boolean => {
|
||||
const [isVisible, setIsVisible] = useState<boolean>(() => getDocumentAutoFetchVisibility());
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof document === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const syncVisibility = () => {
|
||||
setIsVisible(getDocumentAutoFetchVisibility());
|
||||
};
|
||||
|
||||
syncVisibility();
|
||||
document.addEventListener('visibilitychange', syncVisibility);
|
||||
window.addEventListener('focus', syncVisibility);
|
||||
window.addEventListener('pageshow', syncVisibility);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('visibilitychange', syncVisibility);
|
||||
window.removeEventListener('focus', syncVisibility);
|
||||
window.removeEventListener('pageshow', syncVisibility);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return isVisible;
|
||||
};
|
||||
Reference in New Issue
Block a user