Retry library pulls after Comfy finishes and fall back to disk.
Long jobs were succeeding on Beast then failing the save step when /view briefly dropped; retries plus host-agent file serving keep finished MP4s from being orphaned. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import http from 'node:http'
|
||||
import net from 'node:net'
|
||||
import { execFile, spawn } from 'node:child_process'
|
||||
import { promisify } from 'node:util'
|
||||
import { readdirSync, existsSync, rmSync, readFileSync, openSync, mkdirSync, writeFileSync, unlinkSync, statSync } from 'node:fs'
|
||||
import { readdirSync, existsSync, rmSync, readFileSync, openSync, mkdirSync, writeFileSync, unlinkSync, statSync, createReadStream } from 'node:fs'
|
||||
import { basename, dirname, join, resolve, relative, isAbsolute } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
|
||||
@@ -594,6 +594,42 @@ function safeFile(root, subfolder, filename) {
|
||||
return target
|
||||
}
|
||||
|
||||
function findOutputFile(filename, subfolder, type) {
|
||||
const roots = rootsForType(type || 'output')
|
||||
const subs = [...new Set([String(subfolder || ''), type === 'input' ? '' : 'video', type === 'input' ? '' : 'audio', ''])]
|
||||
for (const root of roots) {
|
||||
if (!existsSync(root)) continue
|
||||
for (const sub of subs) {
|
||||
const path = safeFile(root, sub, filename)
|
||||
if (path && existsSync(path)) {
|
||||
try {
|
||||
if (statSync(path).isFile()) return path
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function streamFile(res, path) {
|
||||
const size = statSync(path).size
|
||||
const lower = path.toLowerCase()
|
||||
const type = lower.endsWith('.mp4') ? 'video/mp4'
|
||||
: lower.endsWith('.webm') ? 'video/webm'
|
||||
: lower.endsWith('.flac') ? 'audio/flac'
|
||||
: lower.endsWith('.wav') ? 'audio/wav'
|
||||
: lower.endsWith('.mp3') ? 'audio/mpeg'
|
||||
: lower.endsWith('.png') ? 'image/png'
|
||||
: lower.endsWith('.jpg') || lower.endsWith('.jpeg') ? 'image/jpeg'
|
||||
: 'application/octet-stream'
|
||||
res.writeHead(200, {
|
||||
'Content-Type': type,
|
||||
'Content-Length': size,
|
||||
'Cache-Control': 'no-store'
|
||||
})
|
||||
createReadStream(path).pipe(res)
|
||||
}
|
||||
|
||||
function removeFile(path) {
|
||||
if (!path || !existsSync(path)) return false
|
||||
try {
|
||||
@@ -845,6 +881,15 @@ const server = http.createServer(async (req, res) => {
|
||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'stopped', reason: 'stop', killed }))
|
||||
return json(res, 200, { ok: true, stopped: true, asleep: true, killed })
|
||||
}
|
||||
if (req.method === 'GET' && url.pathname === '/view') {
|
||||
const filename = String(url.searchParams.get('filename') || '')
|
||||
const subfolder = String(url.searchParams.get('subfolder') || '')
|
||||
const type = String(url.searchParams.get('type') || 'output')
|
||||
const path = findOutputFile(filename, subfolder, type)
|
||||
if (!path) return json(res, 404, { ok: false, error: 'not-found', filename, subfolder, type })
|
||||
markWork()
|
||||
return streamFile(res, path)
|
||||
}
|
||||
if (req.method === 'POST' && url.pathname === '/purge') {
|
||||
const body = await readJson(req)
|
||||
return json(res, 200, purgeDesktopFiles(body))
|
||||
|
||||
Reference in New Issue
Block a user