Refuse to start Comfy while AITraining has the GPU.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,18 +12,43 @@ const proxyPort = Number(process.env.COMFY_PROXY_PORT || 8198)
|
||||
const token = process.env.COMFY_CONTROL_TOKEN || ''
|
||||
const defaultHttp = (process.env.COMFY_HOST || 'http://127.0.0.1:8188').replace(/\/$/, '')
|
||||
const idleMs = Math.max(60_000, Number(process.env.COMFY_IDLE_MS || 30 * 60 * 1000) || 30 * 60 * 1000)
|
||||
const trainingUrl = String(process.env.TRAINING_CONTROL_URL || 'http://127.0.0.1:8200').replace(/\/$/, '')
|
||||
|
||||
let lastWorkAt = Date.now()
|
||||
let lastQueueRunning = 0
|
||||
let stoppedByAgent = false
|
||||
let lastHealthyPort = 0
|
||||
let lastProcessUp = false
|
||||
let lastTraining = { busy: false, jobId: null, status: null, name: null, message: '' }
|
||||
|
||||
function markWork() {
|
||||
lastWorkAt = Date.now()
|
||||
stoppedByAgent = false
|
||||
}
|
||||
|
||||
async function trainingLock() {
|
||||
try {
|
||||
const res = await fetch(`${trainingUrl}/status`, { signal: AbortSignal.timeout(2500) })
|
||||
const body = await res.json().catch(() => null)
|
||||
const job = body?.job
|
||||
const status = String(job?.status || '')
|
||||
const busy = Boolean(job && ['preparing', 'queued', 'running', 'stopping'].includes(status))
|
||||
lastTraining = {
|
||||
busy,
|
||||
jobId: job?.id || null,
|
||||
status: busy ? status : null,
|
||||
name: busy ? (job?.outputName || null) : null,
|
||||
message: busy
|
||||
? `AITraining is ${status}${job?.outputName ? ` (${job.outputName})` : ''}. Stop that job before poking Comfy.`
|
||||
: ''
|
||||
}
|
||||
return lastTraining
|
||||
} catch {
|
||||
lastTraining = { busy: false, jobId: null, status: null, name: null, message: '' }
|
||||
return lastTraining
|
||||
}
|
||||
}
|
||||
|
||||
function json(res, status, body) {
|
||||
const payload = JSON.stringify(body)
|
||||
res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) })
|
||||
@@ -603,10 +628,20 @@ const server = http.createServer(async (req, res) => {
|
||||
lastActivityAt: new Date(lastWorkAt).toISOString(),
|
||||
idleMs,
|
||||
port: healthyPort || null,
|
||||
proxyPort: healthyPort ? proxyPort : null
|
||||
proxyPort: healthyPort ? proxyPort : null,
|
||||
training: lastTraining
|
||||
})
|
||||
}
|
||||
if (req.method === 'POST' && url.pathname === '/start') {
|
||||
const training = await trainingLock()
|
||||
if (training.busy) {
|
||||
return json(res, 409, {
|
||||
ok: false,
|
||||
error: 'train-busy',
|
||||
message: training.message,
|
||||
training
|
||||
})
|
||||
}
|
||||
const healthyPort = await syncProxy()
|
||||
if (healthyPort) {
|
||||
markWork()
|
||||
@@ -663,6 +698,8 @@ server.listen(port, '0.0.0.0', async () => {
|
||||
idleMs,
|
||||
candidates: candidatePorts()
|
||||
}))
|
||||
void trainingLock()
|
||||
setInterval(() => { void trainingLock() }, 3000)
|
||||
let lastIdleCheck = 0
|
||||
setInterval(() => {
|
||||
syncProxy().then(async (nextPort) => {
|
||||
|
||||
Reference in New Issue
Block a user