Start I2V when Beast is idle instead of queuing behind leftover jobs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 17:45:32 -05:00
co-authored by Cursor
parent 2171ad3b44
commit 382bd37a3e
5 changed files with 91 additions and 33 deletions
+6 -2
View File
@@ -1,4 +1,4 @@
import { addStudioJob, kickStudioQueue, listStudioJobs } from '~/server/utils/studioQueue'
import { addStudioJob, kickStudioQueue, listStudioJobs, videoJobsBusy } from '~/server/utils/studioQueue'
import { parsePostedLoraStack, listStudioLoras, persistLoraFields } from '~/server/utils/loras'
import { assertImageScaleToTotalPixelsNode, comfyConfigured } from '~/server/utils/comfy'
import { imageDimensions } from '~/server/utils/resolution'
@@ -146,7 +146,11 @@ export default defineEventHandler(async (event) => {
}
})
await kickStudioQueue()
const latest = listStudioJobs(ownerKey).find(item => item.id === studio.id)
let latest = listStudioJobs(ownerKey).find(item => item.id === studio.id)
if (!latest?.liveJobId && !(await videoJobsBusy())) {
await kickStudioQueue()
latest = listStudioJobs(ownerKey).find(item => item.id === studio.id)
}
const liveJobId = latest?.liveJobId || ''
return {
+6 -2
View File
@@ -1,5 +1,5 @@
import { existsSync, readFileSync } from 'node:fs'
import { addStudioJob, kickStudioQueue, listStudioJobs } from '~/server/utils/studioQueue'
import { addStudioJob, kickStudioQueue, listStudioJobs, videoJobsBusy } from '~/server/utils/studioQueue'
import { listStudioLoras, parsePostedLoraStack, parseShotLoraStacks, persistLoraFields } from '~/server/utils/loras'
import type { LoraStackItem } from '~/utils/loras'
import { clampVideoCfg } from '~/utils/generationPresets'
@@ -259,7 +259,11 @@ export default defineEventHandler(async (event) => {
}
})
await kickStudioQueue()
const latest = listStudioJobs(ownerKey).find(item => item.id === studio.id)
let latest = listStudioJobs(ownerKey).find(item => item.id === studio.id)
if (!latest?.liveJobId && !(await videoJobsBusy())) {
await kickStudioQueue()
latest = listStudioJobs(ownerKey).find(item => item.id === studio.id)
}
const liveJobId = latest?.liveJobId || ''
const queueId = latest?.shotQueueId
+29 -7
View File
@@ -1,5 +1,13 @@
function livePayload(job: ReturnType<typeof getJob> & {}) {
if (!job) return null
import { fetchLiveQueue } from '~/server/utils/comfy'
import { jobSnapshot, listJobs, type Job } from '~/server/utils/jobs'
import { libraryOwnerKey } from '~/server/utils/library'
import { listPendingJobs, resolvePendingJob } from '~/server/utils/pending'
import { jobIsLocallySubmitting } from '~/server/utils/studioQueue'
import { ensurePendingWatch } from '~/server/utils/watch'
const SUBMIT_WINDOW_MS = 45 * 1000
function livePayload(job: Job) {
return {
jobId: job.id,
kind: job.kind || 'video',
@@ -9,10 +17,20 @@ function livePayload(job: ReturnType<typeof getJob> & {}) {
}
}
function jobLooksLive(job: Job, comfyBusy: boolean) {
if (job.library?.stopAfterCurrent) return false
if (jobIsLocallySubmitting(job)) return true
if (job.status === 'running' && job.promptId) return comfyBusy
if (job.status === 'queued' && Date.now() - job.startedAt < SUBMIT_WINDOW_MS) return true
return false
}
export default defineEventHandler(async (event) => {
const owner = libraryOwnerKey(event)
const queue = await fetchLiveQueue()
const comfyBusy = queue ? queue.running > 0 || queue.pending > 0 : true
const live = listJobs()
.filter(job => job.library?.ownerKey === owner && (job.status === 'queued' || job.status === 'uploading' || job.status === 'running'))
.filter(job => job.library?.ownerKey === owner && jobLooksLive(job, comfyBusy))
.sort((a, b) => b.startedAt - a.startedAt)
const videoLive = live.find(job => job.kind !== 'edit')
const editLive = live.find(job => job.kind === 'edit')
@@ -22,11 +40,15 @@ export default defineEventHandler(async (event) => {
if (!video) {
const pending = listPendingJobs()
.filter(job => job.ownerKey === owner)
.filter(job => (
job.ownerKey === owner
&& !job.stopAfterCurrent
&& Date.now() - job.startedAt < SUBMIT_WINDOW_MS * 4
))
.sort((a, b) => b.startedAt - a.startedAt)[0]
if (pending) {
if (pending && comfyBusy) {
const resolved = await resolvePendingJob(pending).catch(() => null)
if (resolved) {
if (resolved && resolved.status !== 'complete' && resolved.status !== 'error') {
video = {
jobId: pending.jobId,
kind: 'video' as const,
@@ -34,7 +56,7 @@ export default defineEventHandler(async (event) => {
folderLocked: pending.folderLocked === true,
...resolved
}
} else {
} else if (!resolved) {
const job = ensurePendingWatch(pending)
video = {
jobId: pending.jobId,