all apps are http apps
This commit is contained in:
parent
fecc074757
commit
96083b640f
|
|
@ -43,7 +43,6 @@ let _shuttingDown = false
|
||||||
export type App = SharedApp & {
|
export type App = SharedApp & {
|
||||||
consecutiveHealthFailures?: number
|
consecutiveHealthFailures?: number
|
||||||
healthCheckTimer?: Timer
|
healthCheckTimer?: Timer
|
||||||
isHttpApp?: boolean
|
|
||||||
lastRestartTime?: number
|
lastRestartTime?: number
|
||||||
manuallyStopped?: boolean
|
manuallyStopped?: boolean
|
||||||
proc?: Subprocess
|
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) {
|
if (app.startupTimer) {
|
||||||
clearTimeout(app.startupTimer)
|
clearTimeout(app.startupTimer)
|
||||||
app.startupTimer = undefined
|
app.startupTimer = undefined
|
||||||
}
|
}
|
||||||
app.state = 'running'
|
app.state = 'running'
|
||||||
app.started = Date.now()
|
app.started = Date.now()
|
||||||
app.isHttpApp = isHttpApp
|
|
||||||
update()
|
update()
|
||||||
emit({ type: 'app:start', app: app.name })
|
emit({ type: 'app:start', app: app.name })
|
||||||
publishApp(app.name)
|
publishApp(app.name)
|
||||||
openTunnelIfEnabled(app.name, port)
|
openTunnelIfEnabled(app.name, port)
|
||||||
|
|
||||||
if (isHttpApp) {
|
|
||||||
startHealthChecks(app, port)
|
startHealthChecks(app, port)
|
||||||
} else {
|
|
||||||
startProcessHealthChecks(app)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadApp(dir: string): LoadResult {
|
function loadApp(dir: string): LoadResult {
|
||||||
|
|
@ -645,11 +638,9 @@ async function runApp(dir: string, port: number) {
|
||||||
|
|
||||||
app.proc = proc
|
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 pollStartup = async () => {
|
||||||
const pollInterval = 500
|
const pollInterval = 500
|
||||||
const survivalThreshold = 5000 // Consider non-HTTP apps running after 5s
|
|
||||||
const startTime = Date.now()
|
|
||||||
|
|
||||||
while (app.state === 'starting' && app.proc === proc) {
|
while (app.state === 'starting' && app.proc === proc) {
|
||||||
if (proc.exitCode !== null) {
|
if (proc.exitCode !== null) {
|
||||||
|
|
@ -657,7 +648,6 @@ async function runApp(dir: string, port: number) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try /ok endpoint for HTTP apps
|
|
||||||
try {
|
try {
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
const timeout = setTimeout(() => controller.abort(), 2000)
|
const timeout = setTimeout(() => controller.abort(), 2000)
|
||||||
|
|
@ -667,8 +657,7 @@ async function runApp(dir: string, port: number) {
|
||||||
clearTimeout(timeout)
|
clearTimeout(timeout)
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
// HTTP app is running and healthy
|
markAsRunning(app, port)
|
||||||
markAsRunning(app, port, true)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,18 +667,7 @@ async function runApp(dir: string, port: number) {
|
||||||
app.proc?.kill()
|
app.proc?.kill()
|
||||||
return
|
return
|
||||||
} catch {
|
} catch {
|
||||||
// Connection failed - app not ready yet or not an HTTP app
|
// Connection failed - app not ready yet
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, pollInterval))
|
await new Promise(resolve => setTimeout(resolve, pollInterval))
|
||||||
|
|
@ -854,13 +832,6 @@ function startHealthChecks(app: App, port: number) {
|
||||||
}, HEALTH_CHECK_INTERVAL)
|
}, 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) {
|
function startShutdownTimeout(app: App) {
|
||||||
app.shutdownTimer = setTimeout(() => {
|
app.shutdownTimer = setTimeout(() => {
|
||||||
if (app.proc && (app.state === 'stopping' || app.state === 'running')) {
|
if (app.proc && (app.state === 'stopping' || app.state === 'running')) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user