fix: 避免过期连接尝试残留错误提示

Co-authored-by: staff <staff@qimaos-MacBook-Pro.local>
This commit is contained in:
zipg
2026-06-26 12:32:02 +08:00
committed by GitHub
co-authored by staff
parent 546a59b1e3
commit d6052cff8b
2 changed files with 56 additions and 1 deletions
@@ -83,6 +83,38 @@ describe("connectionStore MQ sidebar tree", () => {
expect(node.isExpanded).toBe(true);
});
it("reuses an in-flight connection attempt instead of recording stale superseded errors", async () => {
let resolveConnect: ((value: string) => void) | undefined;
const connectDb = vi.fn(
() =>
new Promise<string>((resolve) => {
resolveConnect = resolve;
}),
);
vi.doMock("@/lib/tauriRuntime", () => ({ isTauriRuntime: () => false }));
vi.doMock("@/lib/api", () => ({
checkConnectionHealth: vi.fn().mockResolvedValue(undefined),
connectDb,
}));
const { useConnectionStore } = await import("@/stores/connectionStore");
const store = useConnectionStore();
const connection = mqConnection();
store.connections = [connection];
const first = store.ensureConnected(connection.id);
const second = store.ensureConnected(connection.id);
await Promise.resolve();
expect(connectDb).toHaveBeenCalledTimes(1);
resolveConnect?.(connection.id);
await Promise.all([first, second]);
expect(store.connectedIds.has(connection.id)).toBe(true);
expect(store.connectionErrors[connection.id]).toBeUndefined();
});
it("stores the selected tenant when opening an MQ admin tab", async () => {
const { useConnectionStore } = await import("@/stores/connectionStore");
const { useQueryStore } = await import("@/stores/queryStore");
+24 -1
View File
@@ -63,6 +63,7 @@ const METADATA_LOAD_DISABLED_QUERY_TIMEOUT_MS = 60_000;
const DISCONNECT_REQUEST_TIMEOUT_MS = 5_000;
const MONGO_LEGACY_DRIVER_PROFILE = "mongodb-legacy";
const MONGO_LEGACY_DRIVER_LABEL = "MongoDB (Legacy)";
const SUPERSEDED_CONNECTION_ATTEMPT_MESSAGE = "Connection attempt was superseded by a newer attempt";
function sidebarObjectGroupPageSize(): number {
const settingsStore = useSettingsStore();
const size = settingsStore.desktopSettings.sidebar_table_page_size;
@@ -224,6 +225,7 @@ export const useConnectionStore = defineStore("connection", () => {
const sidebarLayout = ref<SidebarLayout>(emptyLayout());
let layoutPersistTimer: ReturnType<typeof setTimeout> | null = null;
const staleTreeRefreshIds = new Set<string>();
const connectInFlight = new Map<string, Promise<void>>();
let beforeConnectHandler: BeforeConnectHandler | null = null;
let initFromDiskPromise: Promise<void> | null = null;
@@ -255,6 +257,10 @@ export const useConnectionStore = defineStore("connection", () => {
return String(error);
}
function isSupersededConnectionAttempt(error: unknown): boolean {
return connectionErrorMessage(error).includes(SUPERSEDED_CONNECTION_ATTEMPT_MESSAGE);
}
function setConnectionError(connectionId: string, message: string) {
connectionErrors.value[connectionId] = message;
}
@@ -1196,7 +1202,12 @@ export const useConnectionStore = defineStore("connection", () => {
recordConnectionError(connectionId, error);
throw error;
}
try {
const existingConnect = connectInFlight.get(connectionId);
if (existingConnect) {
await existingConnect;
return;
}
const connectPromise = (async () => {
await beforeConnectHandler?.(config);
await withConnectionAttemptTimeout(api.connectDb(config), config);
await syncMongoLegacyDriverFallback(connectionId, config);
@@ -1204,9 +1215,21 @@ export const useConnectionStore = defineStore("connection", () => {
markConnectionHealthChecked(connectionId);
activeConnectionId.value = connectionId;
clearConnectionError(connectionId);
})();
connectInFlight.set(connectionId, connectPromise);
try {
await connectPromise;
} catch (e) {
if (isSupersededConnectionAttempt(e) && connectedIds.value.has(connectionId)) {
clearConnectionError(connectionId);
return;
}
recordConnectionError(connectionId, e);
throw e;
} finally {
if (connectInFlight.get(connectionId) === connectPromise) {
connectInFlight.delete(connectionId);
}
}
}