三层防护: - MySQL 连接获取时执行 ping 健康检查,死连接自动重连 - macOS Reopen 事件 + 前端 visibilitychange 触发连接刷新 - 前端 Promise.race 超时保护,确保 loading 状态不会超过 60s
33 lines
902 B
TypeScript
33 lines
902 B
TypeScript
import { onMounted, onUnmounted } from "vue";
|
|
import { refreshConnections } from "@/lib/api";
|
|
import { useQueryStore } from "@/stores/queryStore";
|
|
|
|
let hiddenAt: number | null = null;
|
|
|
|
function handleVisibilityChange() {
|
|
if (document.hidden) {
|
|
hiddenAt = Date.now();
|
|
} else {
|
|
const wasHidden = hiddenAt;
|
|
hiddenAt = null;
|
|
if (wasHidden && Date.now() - wasHidden > 30_000) {
|
|
refreshConnections().catch(() => {});
|
|
const queryStore = useQueryStore();
|
|
const stuckTabs = queryStore.tabs.filter((t) => t.isExecuting);
|
|
if (stuckTabs.length > 0) {
|
|
queryStore.notifyConnectionMayBeLost();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export function useVisibilityChange() {
|
|
onMounted(() => {
|
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
});
|
|
}
|