Fix Comfy wake: launch when HTTP is down instead of treating leftover Python as already booting.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -16,6 +16,7 @@ const trainingUrl = String(process.env.TRAINING_CONTROL_URL || 'http://127.0.0.1
|
||||
|
||||
let lastWorkAt = Date.now()
|
||||
let lastQueueRunning = 0
|
||||
let lastLaunchAt = 0
|
||||
let stoppedByAgent = false
|
||||
let lastHealthyPort = 0
|
||||
let lastProcessUp = false
|
||||
@@ -162,12 +163,23 @@ function ensureProxy(targetPort) {
|
||||
})
|
||||
}
|
||||
|
||||
function markAsleep() {
|
||||
stoppedByAgent = true
|
||||
lastQueueRunning = 0
|
||||
lastHealthyPort = 0
|
||||
lastProcessUp = false
|
||||
lastLaunchAt = 0
|
||||
proxyTarget = 0
|
||||
}
|
||||
|
||||
async function syncProxy() {
|
||||
const healthyPort = await findHealthyPort()
|
||||
lastHealthyPort = healthyPort || 0
|
||||
if (healthyPort) {
|
||||
ensureProxy(healthyPort)
|
||||
lastProcessUp = true
|
||||
} else {
|
||||
lastProcessUp = false
|
||||
}
|
||||
return healthyPort
|
||||
}
|
||||
@@ -493,10 +505,7 @@ async function maybeIdleStop(healthyPort) {
|
||||
http: Boolean(healthyPort)
|
||||
}))
|
||||
const killed = await stopComfyProcesses()
|
||||
stoppedByAgent = true
|
||||
lastQueueRunning = 0
|
||||
lastHealthyPort = 0
|
||||
lastProcessUp = false
|
||||
markAsleep()
|
||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'stopped', reason: 'idle', killed }))
|
||||
}
|
||||
|
||||
@@ -617,14 +626,18 @@ const server = http.createServer(async (req, res) => {
|
||||
if (req.method === 'GET' && url.pathname === '/status') {
|
||||
// Answer immediately. MyMonitor allows ~500ms; probing ports + WMI here
|
||||
// made the A light stay red even while this process was running.
|
||||
const healthyPort = lastHealthyPort || proxyTarget
|
||||
const processUpNow = Boolean(lastProcessUp || healthyPort)
|
||||
// Do not treat a stale proxyTarget as proof Comfy is up — that made
|
||||
// /status report asleep+http at once, so training skipped /stop.
|
||||
const healthyPort = lastHealthyPort || 0
|
||||
const processUpNow = Boolean(lastProcessUp && healthyPort)
|
||||
const asleep = !healthyPort && !processUpNow
|
||||
if (!asleep) stoppedByAgent = false
|
||||
return json(res, 200, {
|
||||
ok: true,
|
||||
http: Boolean(healthyPort),
|
||||
process: processUpNow,
|
||||
processUp: processUpNow,
|
||||
asleep: Boolean(stoppedByAgent || (!healthyPort && !processUpNow)),
|
||||
asleep,
|
||||
lastActivityAt: new Date(lastWorkAt).toISOString(),
|
||||
idleMs,
|
||||
port: healthyPort || null,
|
||||
@@ -647,11 +660,12 @@ const server = http.createServer(async (req, res) => {
|
||||
markWork()
|
||||
return json(res, 200, { ok: true, started: false, already: true, asleep: false, port: healthyPort, proxyPort })
|
||||
}
|
||||
if (await pythonMainUp()) {
|
||||
if (lastLaunchAt && Date.now() - lastLaunchAt < 60_000) {
|
||||
return json(res, 200, { ok: true, started: false, already: true, booting: true, asleep: false })
|
||||
}
|
||||
await taskkillImage('Comfy Desktop.exe')
|
||||
stoppedByAgent = false
|
||||
lastLaunchAt = Date.now()
|
||||
const launched = await startComfy()
|
||||
if (launched.port) {
|
||||
lastProcessUp = true
|
||||
@@ -671,10 +685,7 @@ const server = http.createServer(async (req, res) => {
|
||||
})
|
||||
}
|
||||
const killed = await stopComfyProcesses()
|
||||
stoppedByAgent = true
|
||||
lastQueueRunning = 0
|
||||
lastHealthyPort = 0
|
||||
lastProcessUp = false
|
||||
markAsleep()
|
||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'stopped', reason: 'stop', killed }))
|
||||
return json(res, 200, { ok: true, stopped: true, asleep: true, killed })
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ export async function requestComfyWake() {
|
||||
statusMessage: 'COMFY_CONTROL_URL is not set. The studio cannot poke the Beast host agent.'
|
||||
})
|
||||
}
|
||||
const remote = await controlRequest('/start', 'POST')
|
||||
const remote = await controlRequest('/start', 'POST', 25_000)
|
||||
if (!remote) {
|
||||
throw createError({
|
||||
statusCode: 503,
|
||||
@@ -263,7 +263,7 @@ async function startComfy() {
|
||||
}
|
||||
lastStartAt = now
|
||||
|
||||
const remote = await controlRequest('/start', 'POST')
|
||||
const remote = await controlRequest('/start', 'POST', 25_000)
|
||||
throwIfTrainingBusy(remote)
|
||||
if (remote?.ok || remote?.started) {
|
||||
log('start-remote', { pid: remote.pid || null })
|
||||
|
||||
@@ -88,7 +88,7 @@ export async function fetchImageQueue() {
|
||||
return fetchQueueAt(getImageComfyHost())
|
||||
}
|
||||
|
||||
async function controlRequest(path: string, method = 'GET') {
|
||||
async function controlRequest(path: string, method = 'GET', timeoutMs = 5000) {
|
||||
const { controlUrl, controlToken } = settings()
|
||||
if (!controlUrl) return null
|
||||
try {
|
||||
@@ -98,7 +98,7 @@ async function controlRequest(path: string, method = 'GET') {
|
||||
Accept: 'application/json',
|
||||
...(controlToken ? { Authorization: `Bearer ${controlToken}` } : {})
|
||||
},
|
||||
signal: AbortSignal.timeout(5000)
|
||||
signal: AbortSignal.timeout(timeoutMs)
|
||||
})
|
||||
if (!res.ok) return { ok: false, status: res.status }
|
||||
return await res.json() as {
|
||||
@@ -154,7 +154,7 @@ async function startImageComfy() {
|
||||
return { started: false, reason: 'recent-start' as const }
|
||||
}
|
||||
lastStartAt = now
|
||||
const remote = await controlRequest('/start', 'POST')
|
||||
const remote = await controlRequest('/start', 'POST', 25_000)
|
||||
if (remote?.ok || remote?.started) {
|
||||
log('start-remote', { port: remote.port || null })
|
||||
return { started: true, reason: 'remote' as const }
|
||||
|
||||
Reference in New Issue
Block a user