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 lastWorkAt = Date.now()
|
||||||
let lastQueueRunning = 0
|
let lastQueueRunning = 0
|
||||||
|
let lastLaunchAt = 0
|
||||||
let stoppedByAgent = false
|
let stoppedByAgent = false
|
||||||
let lastHealthyPort = 0
|
let lastHealthyPort = 0
|
||||||
let lastProcessUp = false
|
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() {
|
async function syncProxy() {
|
||||||
const healthyPort = await findHealthyPort()
|
const healthyPort = await findHealthyPort()
|
||||||
lastHealthyPort = healthyPort || 0
|
lastHealthyPort = healthyPort || 0
|
||||||
if (healthyPort) {
|
if (healthyPort) {
|
||||||
ensureProxy(healthyPort)
|
ensureProxy(healthyPort)
|
||||||
lastProcessUp = true
|
lastProcessUp = true
|
||||||
|
} else {
|
||||||
|
lastProcessUp = false
|
||||||
}
|
}
|
||||||
return healthyPort
|
return healthyPort
|
||||||
}
|
}
|
||||||
@@ -493,10 +505,7 @@ async function maybeIdleStop(healthyPort) {
|
|||||||
http: Boolean(healthyPort)
|
http: Boolean(healthyPort)
|
||||||
}))
|
}))
|
||||||
const killed = await stopComfyProcesses()
|
const killed = await stopComfyProcesses()
|
||||||
stoppedByAgent = true
|
markAsleep()
|
||||||
lastQueueRunning = 0
|
|
||||||
lastHealthyPort = 0
|
|
||||||
lastProcessUp = false
|
|
||||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'stopped', reason: 'idle', killed }))
|
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') {
|
if (req.method === 'GET' && url.pathname === '/status') {
|
||||||
// Answer immediately. MyMonitor allows ~500ms; probing ports + WMI here
|
// Answer immediately. MyMonitor allows ~500ms; probing ports + WMI here
|
||||||
// made the A light stay red even while this process was running.
|
// made the A light stay red even while this process was running.
|
||||||
const healthyPort = lastHealthyPort || proxyTarget
|
// Do not treat a stale proxyTarget as proof Comfy is up — that made
|
||||||
const processUpNow = Boolean(lastProcessUp || healthyPort)
|
// /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, {
|
return json(res, 200, {
|
||||||
ok: true,
|
ok: true,
|
||||||
http: Boolean(healthyPort),
|
http: Boolean(healthyPort),
|
||||||
process: processUpNow,
|
process: processUpNow,
|
||||||
processUp: processUpNow,
|
processUp: processUpNow,
|
||||||
asleep: Boolean(stoppedByAgent || (!healthyPort && !processUpNow)),
|
asleep,
|
||||||
lastActivityAt: new Date(lastWorkAt).toISOString(),
|
lastActivityAt: new Date(lastWorkAt).toISOString(),
|
||||||
idleMs,
|
idleMs,
|
||||||
port: healthyPort || null,
|
port: healthyPort || null,
|
||||||
@@ -647,11 +660,12 @@ const server = http.createServer(async (req, res) => {
|
|||||||
markWork()
|
markWork()
|
||||||
return json(res, 200, { ok: true, started: false, already: true, asleep: false, port: healthyPort, proxyPort })
|
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 })
|
return json(res, 200, { ok: true, started: false, already: true, booting: true, asleep: false })
|
||||||
}
|
}
|
||||||
await taskkillImage('Comfy Desktop.exe')
|
await taskkillImage('Comfy Desktop.exe')
|
||||||
stoppedByAgent = false
|
stoppedByAgent = false
|
||||||
|
lastLaunchAt = Date.now()
|
||||||
const launched = await startComfy()
|
const launched = await startComfy()
|
||||||
if (launched.port) {
|
if (launched.port) {
|
||||||
lastProcessUp = true
|
lastProcessUp = true
|
||||||
@@ -671,10 +685,7 @@ const server = http.createServer(async (req, res) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
const killed = await stopComfyProcesses()
|
const killed = await stopComfyProcesses()
|
||||||
stoppedByAgent = true
|
markAsleep()
|
||||||
lastQueueRunning = 0
|
|
||||||
lastHealthyPort = 0
|
|
||||||
lastProcessUp = false
|
|
||||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'stopped', reason: 'stop', killed }))
|
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'stopped', reason: 'stop', killed }))
|
||||||
return json(res, 200, { ok: true, stopped: true, asleep: true, 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.'
|
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) {
|
if (!remote) {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 503,
|
statusCode: 503,
|
||||||
@@ -263,7 +263,7 @@ async function startComfy() {
|
|||||||
}
|
}
|
||||||
lastStartAt = now
|
lastStartAt = now
|
||||||
|
|
||||||
const remote = await controlRequest('/start', 'POST')
|
const remote = await controlRequest('/start', 'POST', 25_000)
|
||||||
throwIfTrainingBusy(remote)
|
throwIfTrainingBusy(remote)
|
||||||
if (remote?.ok || remote?.started) {
|
if (remote?.ok || remote?.started) {
|
||||||
log('start-remote', { pid: remote.pid || null })
|
log('start-remote', { pid: remote.pid || null })
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export async function fetchImageQueue() {
|
|||||||
return fetchQueueAt(getImageComfyHost())
|
return fetchQueueAt(getImageComfyHost())
|
||||||
}
|
}
|
||||||
|
|
||||||
async function controlRequest(path: string, method = 'GET') {
|
async function controlRequest(path: string, method = 'GET', timeoutMs = 5000) {
|
||||||
const { controlUrl, controlToken } = settings()
|
const { controlUrl, controlToken } = settings()
|
||||||
if (!controlUrl) return null
|
if (!controlUrl) return null
|
||||||
try {
|
try {
|
||||||
@@ -98,7 +98,7 @@ async function controlRequest(path: string, method = 'GET') {
|
|||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
...(controlToken ? { Authorization: `Bearer ${controlToken}` } : {})
|
...(controlToken ? { Authorization: `Bearer ${controlToken}` } : {})
|
||||||
},
|
},
|
||||||
signal: AbortSignal.timeout(5000)
|
signal: AbortSignal.timeout(timeoutMs)
|
||||||
})
|
})
|
||||||
if (!res.ok) return { ok: false, status: res.status }
|
if (!res.ok) return { ok: false, status: res.status }
|
||||||
return await res.json() as {
|
return await res.json() as {
|
||||||
@@ -154,7 +154,7 @@ async function startImageComfy() {
|
|||||||
return { started: false, reason: 'recent-start' as const }
|
return { started: false, reason: 'recent-start' as const }
|
||||||
}
|
}
|
||||||
lastStartAt = now
|
lastStartAt = now
|
||||||
const remote = await controlRequest('/start', 'POST')
|
const remote = await controlRequest('/start', 'POST', 25_000)
|
||||||
if (remote?.ok || remote?.started) {
|
if (remote?.ok || remote?.started) {
|
||||||
log('start-remote', { port: remote.port || null })
|
log('start-remote', { port: remote.port || null })
|
||||||
return { started: true, reason: 'remote' as const }
|
return { started: true, reason: 'remote' as const }
|
||||||
|
|||||||
Reference in New Issue
Block a user