mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-09 14:31:35 +08:00
🐛 fix(connection): 修复失败连接高频重试并暂停后台自动元数据拉取 #331
- 后端为失败数据库连接增加冷却窗口,避免短时间内重复真实建连 - 补充失败冷却回归测试,覆盖重复失败、冷却后重试和成功后清理场景 - 前端在后台态暂停查询页、侧边栏和表概览的自动元数据拉取 - 保持手动刷新、手动展开等显式操作行为不变
This commit is contained in:
@@ -11,6 +11,7 @@ import DataGrid, { GONAVI_ROW_KEY } from './DataGrid';
|
||||
import { getDataSourceCapabilities } from '../utils/dataSourceCapabilities';
|
||||
import { convertMongoShellToJsonCommand } from '../utils/mongodb';
|
||||
import { getShortcutDisplay, isEditableElement, isShortcutMatch } from '../utils/shortcuts';
|
||||
import { useAutoFetchVisibility } from '../utils/autoFetchVisibility';
|
||||
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
|
||||
|
||||
const SQL_KEYWORDS = [
|
||||
@@ -249,6 +250,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
||||
const setQueryOptions = useStore(state => state.setQueryOptions);
|
||||
const shortcutOptions = useStore(state => state.shortcutOptions);
|
||||
const activeTabId = useStore(state => state.activeTabId);
|
||||
const autoFetchVisible = useAutoFetchVisibility();
|
||||
|
||||
const currentSavedQuery = useMemo(() => {
|
||||
const savedId = String(tab.savedQueryId || '').trim();
|
||||
@@ -324,6 +326,10 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
||||
|
||||
// Fetch Database List
|
||||
useEffect(() => {
|
||||
if (!autoFetchVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchDbs = async () => {
|
||||
const conn = connections.find(c => c.id === currentConnectionId);
|
||||
if (!conn) return;
|
||||
@@ -367,10 +373,14 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
||||
}
|
||||
};
|
||||
void fetchDbs();
|
||||
}, [currentConnectionId, connections]);
|
||||
}, [autoFetchVisible, currentConnectionId, connections]);
|
||||
|
||||
// Fetch Metadata for Autocomplete (Cross-database)
|
||||
useEffect(() => {
|
||||
if (!autoFetchVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchMetadata = async () => {
|
||||
const conn = connections.find(c => c.id === currentConnectionId);
|
||||
if (!conn) return;
|
||||
@@ -424,7 +434,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
||||
}
|
||||
};
|
||||
void fetchMetadata();
|
||||
}, [currentConnectionId, connections, dbList]); // dbList 变化时触发重新加载
|
||||
}, [autoFetchVisible, currentConnectionId, connections, dbList]); // dbList 变化时触发重新加载
|
||||
|
||||
// Query ID management helpers
|
||||
const setQueryId = (id: string) => {
|
||||
|
||||
@@ -41,6 +41,7 @@ import { getDbIcon } from './DatabaseIcons';
|
||||
import { DBGetDatabases, DBGetTables, DBQuery, DBShowCreateTable, ExportTable, OpenSQLFile, ExecuteSQLFile, CancelSQLFileExecution, CreateDatabase, RenameDatabase, DropDatabase, RenameTable, DropTable, DropView, DropFunction, RenameView } from '../../wailsjs/go/app/App';
|
||||
import { EventsOn } from '../../wailsjs/runtime/runtime';
|
||||
import { normalizeOpacityForPlatform, resolveAppearanceValues } from '../utils/appearance';
|
||||
import { useAutoFetchVisibility } from '../utils/autoFetchVisibility';
|
||||
import FindInDatabaseModal from './FindInDatabaseModal';
|
||||
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
|
||||
|
||||
@@ -118,6 +119,7 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
|
||||
const darkMode = theme === 'dark';
|
||||
const resolvedAppearance = resolveAppearanceValues(appearance);
|
||||
const opacity = normalizeOpacityForPlatform(resolvedAppearance.opacity);
|
||||
const autoFetchVisible = useAutoFetchVisibility();
|
||||
const [treeData, setTreeData] = useState<TreeNode[]>([]);
|
||||
|
||||
// Background Helper (Duplicate logic for now, ideally shared)
|
||||
@@ -292,6 +294,10 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
|
||||
const [findInDbContext, setFindInDbContext] = useState<{ open: boolean; connectionId: string; dbName: string }>({ open: false, connectionId: '', dbName: '' });
|
||||
|
||||
useEffect(() => {
|
||||
if (!autoFetchVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh queries for expanded databases
|
||||
const findNode = (nodes: TreeNode[], k: React.Key): TreeNode | null => {
|
||||
for (const node of nodes) {
|
||||
@@ -310,7 +316,7 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
|
||||
loadTables(node);
|
||||
}
|
||||
});
|
||||
}, [savedQueries]);
|
||||
}, [autoFetchVisible, savedQueries]);
|
||||
|
||||
useEffect(() => {
|
||||
setTreeData((prev) => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TableOutlined, SearchOutlined, ReloadOutlined, SortAscendingOutlined, D
|
||||
import { useStore } from '../store';
|
||||
import { DBQuery, DBShowCreateTable, ExportTable, DropTable, RenameTable } from '../../wailsjs/go/app/App';
|
||||
import type { TabData } from '../types';
|
||||
import { useAutoFetchVisibility } from '../utils/autoFetchVisibility';
|
||||
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
|
||||
|
||||
interface TableOverviewProps {
|
||||
@@ -151,6 +152,7 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
|
||||
const [viewMode, setViewMode] = useState<ViewMode>('card');
|
||||
|
||||
const connection = useMemo(() => connections.find(c => c.id === tab.connectionId), [connections, tab.connectionId]);
|
||||
const autoFetchVisible = useAutoFetchVisibility();
|
||||
|
||||
const loadData = useCallback(async () => {
|
||||
if (!connection) return;
|
||||
@@ -179,7 +181,12 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
|
||||
}
|
||||
}, [connection, tab.dbName]);
|
||||
|
||||
useEffect(() => { loadData(); }, [loadData]);
|
||||
useEffect(() => {
|
||||
if (!autoFetchVisible) {
|
||||
return;
|
||||
}
|
||||
void loadData();
|
||||
}, [autoFetchVisible, loadData]);
|
||||
|
||||
const sortedFiltered = useMemo(() => {
|
||||
let list = [...tables];
|
||||
|
||||
Reference in New Issue
Block a user