refactor(api): implement caching for tunnel and version status endpoints
This commit is contained in:
@@ -32,6 +32,10 @@ import { syncToJson as syncMitmAliasCache } from "@/lib/mitmAliasCache";
|
||||
|
||||
process.setMaxListeners(20);
|
||||
|
||||
// Defer heavy startup work so the first HTTP request (login → dashboard) isn't
|
||||
// starved by DB cleanup, cloudflared download, lsof/DNS probes and OAuth pings.
|
||||
const STARTUP_DEFER_MS = 3000;
|
||||
|
||||
// Survive Next.js hot reload
|
||||
const g = global.__appSingleton ??= {
|
||||
signalHandlersRegistered: false,
|
||||
@@ -47,23 +51,8 @@ const g = global.__appSingleton ??= {
|
||||
|
||||
export async function initializeApp() {
|
||||
try {
|
||||
await cleanupProviderConnections();
|
||||
const settings = await getSettings();
|
||||
|
||||
// Auto-resume tunnel (once per process)
|
||||
if (settings.tunnelEnabled && !g.tunnelAutoResumed) {
|
||||
g.tunnelAutoResumed = true;
|
||||
console.log("[InitApp] Tunnel was enabled, auto-resuming...");
|
||||
safeRestartTunnel("startup").catch((e) => console.log("[InitApp] Tunnel resume failed:", e.message));
|
||||
}
|
||||
|
||||
// Auto-resume tailscale (once per process)
|
||||
if (settings.tailscaleEnabled && !g.tailscaleAutoResumed) {
|
||||
g.tailscaleAutoResumed = true;
|
||||
console.log("[InitApp] Tailscale was enabled, auto-resuming...");
|
||||
safeRestartTailscale("startup").catch((e) => console.log("[InitApp] Tailscale resume failed:", e.message));
|
||||
}
|
||||
|
||||
// Register cleanup + exit-respawn callback immediately so signals and
|
||||
// unexpected cloudflared exits are handled even during the deferred window.
|
||||
if (!g.signalHandlersRegistered) {
|
||||
const cleanup = () => {
|
||||
try { removeAllDNSEntriesSync(); } catch { /* best effort */ }
|
||||
@@ -76,25 +65,48 @@ export async function initializeApp() {
|
||||
g.signalHandlersRegistered = true;
|
||||
}
|
||||
|
||||
ensureCloudflared().catch(() => {});
|
||||
|
||||
// Sync mitmAlias DB → JSON cache so standalone MITM server can read it
|
||||
syncMitmAliasCache().catch(() => {});
|
||||
|
||||
// Auto-respawn tunnel when cloudflared exits unexpectedly (e.g. network change drop)
|
||||
setTunnelUnexpectedExitCallback(() => {
|
||||
safeRestartTunnel("unexpected-exit").catch(() => {});
|
||||
});
|
||||
|
||||
startWatchdog();
|
||||
startNetworkMonitor();
|
||||
autoStartMitm();
|
||||
startQuotaAutoPing();
|
||||
// Defer the heavy work — nothing here blocks incoming requests.
|
||||
setTimeout(() => {
|
||||
runHeavyStartup().catch((e) => console.error("[InitApp] deferred startup failed:", e.message));
|
||||
}, STARTUP_DEFER_MS);
|
||||
} catch (error) {
|
||||
console.error("[InitApp] Error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function runHeavyStartup() {
|
||||
await cleanupProviderConnections();
|
||||
const settings = await getSettings();
|
||||
|
||||
// Auto-resume tunnel (once per process)
|
||||
if (settings.tunnelEnabled && !g.tunnelAutoResumed) {
|
||||
g.tunnelAutoResumed = true;
|
||||
console.log("[InitApp] Tunnel was enabled, auto-resuming...");
|
||||
safeRestartTunnel("startup").catch((e) => console.log("[InitApp] Tunnel resume failed:", e.message));
|
||||
}
|
||||
|
||||
// Auto-resume tailscale (once per process)
|
||||
if (settings.tailscaleEnabled && !g.tailscaleAutoResumed) {
|
||||
g.tailscaleAutoResumed = true;
|
||||
console.log("[InitApp] Tailscale was enabled, auto-resuming...");
|
||||
safeRestartTailscale("startup").catch((e) => console.log("[InitApp] Tailscale resume failed:", e.message));
|
||||
}
|
||||
|
||||
ensureCloudflared().catch(() => {});
|
||||
|
||||
// Sync mitmAlias DB → JSON cache so standalone MITM server can read it
|
||||
syncMitmAliasCache().catch(() => {});
|
||||
|
||||
startWatchdog();
|
||||
startNetworkMonitor();
|
||||
autoStartMitm();
|
||||
startQuotaAutoPing();
|
||||
}
|
||||
|
||||
async function autoStartMitm() {
|
||||
if (g.mitmStartInProgress) return;
|
||||
g.mitmStartInProgress = true;
|
||||
|
||||
Reference in New Issue
Block a user