diff --git a/src/server/apps.ts b/src/server/apps.ts index 7eaf4fc..cc65a1f 100644 --- a/src/server/apps.ts +++ b/src/server/apps.ts @@ -43,7 +43,6 @@ let _shuttingDown = false export type App = SharedApp & { consecutiveHealthFailures?: number healthCheckTimer?: Timer - isHttpApp?: boolean lastRestartTime?: number manuallyStopped?: boolean proc?: Subprocess @@ -516,24 +515,18 @@ function initPortPool() { } } -function markAsRunning(app: App, port: number, isHttpApp: boolean) { +function markAsRunning(app: App, port: number) { if (app.startupTimer) { clearTimeout(app.startupTimer) app.startupTimer = undefined } app.state = 'running' app.started = Date.now() - app.isHttpApp = isHttpApp update() emit({ type: 'app:start', app: app.name }) publishApp(app.name) openTunnelIfEnabled(app.name, port) - - if (isHttpApp) { - startHealthChecks(app, port) - } else { - startProcessHealthChecks(app) - } + startHealthChecks(app, port) } function loadApp(dir: string): LoadResult { @@ -645,11 +638,9 @@ async function runApp(dir: string, port: number) { app.proc = proc - // Poll to verify app started - tries /ok for HTTP apps, falls back to survival check + // Poll to verify app started - waits for /ok to respond 200 const pollStartup = async () => { const pollInterval = 500 - const survivalThreshold = 5000 // Consider non-HTTP apps running after 5s - const startTime = Date.now() while (app.state === 'starting' && app.proc === proc) { if (proc.exitCode !== null) { @@ -657,7 +648,6 @@ async function runApp(dir: string, port: number) { return } - // Try /ok endpoint for HTTP apps try { const controller = new AbortController() const timeout = setTimeout(() => controller.abort(), 2000) @@ -667,8 +657,7 @@ async function runApp(dir: string, port: number) { clearTimeout(timeout) if (response.ok) { - // HTTP app is running and healthy - markAsRunning(app, port, true) + markAsRunning(app, port) return } @@ -678,18 +667,7 @@ async function runApp(dir: string, port: number) { app.proc?.kill() return } catch { - // Connection failed - app not ready yet or not an HTTP app - } - - // If process survived long enough, consider it running (non-HTTP app) - if (Date.now() - startTime >= survivalThreshold) { - if (proc.exitCode !== null) { - info(app, 'Process died during startup') - return - } - info(app, 'No /ok endpoint, marking as running (process survived 5s)') - markAsRunning(app, port, false) - return + // Connection failed - app not ready yet } await new Promise(resolve => setTimeout(resolve, pollInterval)) @@ -854,13 +832,6 @@ function startHealthChecks(app: App, port: number) { }, HEALTH_CHECK_INTERVAL) } -function startProcessHealthChecks(app: App) { - // For non-HTTP apps, the proc.exited handler is the authoritative death signal. - // No need to poll — when the process dies, proc.exited fires and cleans up. - // This is a no-op; health checks only matter for HTTP apps where the process - // can be alive but the server unresponsive. -} - function startShutdownTimeout(app: App) { app.shutdownTimer = setTimeout(() => { if (app.proc && (app.state === 'stopping' || app.state === 'running')) {