Files
aigen/server/api/interrupt.post.ts
T

70 lines
3.0 KiB
TypeScript

import { emitJob, getJob, listJobs } from '~/server/utils/jobs'
import { interruptComfy } from '~/server/utils/comfy'
import { deletePendingJob } from '~/server/utils/pending'
import { assertLibraryOwner, removeExtendTemp } from '~/server/utils/library'
import { markShotQueueCancelled, pauseShotQueue, setQueueJob } from '~/server/utils/shotQueue'
import { cancelStudioJob, listStudioJobs } from '~/server/utils/studioQueue'
function stopLiveJob(job: NonNullable<ReturnType<typeof getJob>>) {
job.status = 'cancelled'
job.error = 'Job interrupted.'
emitJob(job, { type: 'status', message: 'Cancelling job...' })
removeExtendTemp(job.library?.extendTmpDir)
if (job.library) {
job.library.stopAfterCurrent = true
job.library.queueAutoRun = false
job.library.chainContinuing = false
if (job.library.queueId) {
markShotQueueCancelled(job.library.queueId)
setQueueJob(job.library.queueId, null)
}
}
deletePendingJob(job.id)
emitJob(job, { type: 'error', error: 'Job interrupted.', message: 'Job interrupted.' })
}
export default defineEventHandler(async (event) => {
const body = await readBody<{ jobId?: string; kind?: string }>(event).catch(() => ({}))
const jobId = String(body?.jobId || '')
const kind = String(body?.kind || '')
const named = jobId ? getJob(jobId) : undefined
if (named?.upscale) {
const { owner } = assertLibraryOwner(event)
if (named.library?.ownerKey !== owner) throw createError({ statusCode: 404, statusMessage: 'Job not found' })
const { cancelUpscaleJob } = await import('~/server/utils/videoUpscale')
const { onLiveVideoSettled } = await import('~/server/utils/studioQueue')
await cancelUpscaleJob(named)
await onLiveVideoSettled(named)
return { ok: true, cancelled: 1 }
}
const targets = named
? [named]
: listJobs().filter((job) => {
if (job.upscale) return false
if (job.status === 'complete' || job.status === 'error' || job.status === 'cancelled') return false
if (kind === 'edit') return job.kind === 'edit'
if (kind === 'music') return job.kind === 'music'
if (kind === 'video') return job.kind !== 'edit' && job.kind !== 'music'
return true
})
for (const job of targets) {
stopLiveJob(job)
if (job.library?.queueId && job.library.ownerKey) {
await pauseShotQueue(job.library.ownerKey, job.library.queueId).catch(() => null)
}
}
if (jobId) deletePendingJob(jobId)
const { owner } = assertLibraryOwner(event)
for (const row of listStudioJobs(owner)) {
if (row.payload.upscale) continue
if (row.status !== 'running' && row.status !== 'held') continue
if (kind === 'edit' && row.kind !== 'edit') continue
if (kind === 'music' && row.kind !== 'music') continue
if (kind === 'video' && row.kind === 'edit') continue
if (kind === 'video' && row.kind === 'music') continue
await cancelStudioJob(owner, row.id).catch(() => null)
}
const ok = await interruptComfy()
return { ok, cancelled: targets.length }
})