c9b0f25bb2
Deploy / deploy (push) Successful in 6m11s
Urgent already propagated — a preview inherits its render's priority, so an urgent export stays ahead all the way to QC. The complaint was the other half: at equal priority previews always ran last. The queue orders by priority then age, and a preview job is only created when its render finishes, so it is always newer than the renders queued beside it. Ten shots ran as ten renders and then ten previews, and nothing was reviewable until the end of the batch. render.previewPriorityBoost (default 1) subtracts from the render's priority when the preview is created, so a shot finishes end to end before the next render starts. The boost never promotes a job across the urgent threshold: a normal preview must not inherit permission to run outside the render window that its render never had. Set it to 0 for the old behaviour. Worth knowing separately: a worker will not claim preview jobs at all while an artist has AE open on that machine, which during the day is the larger reason previews appear to wait. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
115 lines
4.8 KiB
TypeScript
115 lines
4.8 KiB
TypeScript
import { db } from "@/lib/db";
|
|
|
|
/**
|
|
* Pipeline-wide settings live in the existing SystemConfig key/value table
|
|
* (RenderPipeline2 §14.1) so the fleet can be tuned without redeploys.
|
|
*/
|
|
export const PIPELINE_CONFIG_DEFAULTS = {
|
|
"render.pollSeconds": 10,
|
|
"render.heartbeatSeconds": 30,
|
|
"render.leaseSeconds": 300,
|
|
"render.maxAttempts": 3,
|
|
"render.stallTimeoutSeconds": 600,
|
|
"render.urgentPriorityThreshold": 20,
|
|
/**
|
|
* How far a preview job outranks the render it follows. A preview is only
|
|
* created when its render finishes, so at equal priority it sorts behind
|
|
* every render queued alongside it — 10 shots run as 10 renders then 10
|
|
* previews, and nothing is reviewable until the end. A boost of 1 finishes
|
|
* shots end to end instead. Set to 0 for the old phase behaviour.
|
|
*/
|
|
"render.previewPriorityBoost": 1,
|
|
"render.outputRoot": "//SAN",
|
|
// Validation stage (§8). Disabling it restores the pre-Phase-3 flow
|
|
// (render → preview) without a redeploy, for a bad engine release.
|
|
"validation.enabled": "true",
|
|
"validation.sampleEvery": 25,
|
|
/** Per-check severity overrides, e.g. {"exr_type":"warn"} (§17.3). */
|
|
"validation.overrides": "{}",
|
|
/** Frames of head handle the plates carry; only used for the API timecode fallback (§8.1a). */
|
|
"validation.handleFrames": 8,
|
|
/**
|
|
* Studio-wide delivery defaults (§11.2). A project's own `deliveryConfig`
|
|
* column overrides these key by key; `{}` falls through to the built-ins in
|
|
* lib/render-pipeline/deliveries.ts.
|
|
*/
|
|
"delivery.defaultConfig": "{}",
|
|
"preview.maxWidth": 1920,
|
|
// Preview stage (§9): headless AE rebuild of the render with slate/burn-ins
|
|
"preview.enabled": "true",
|
|
"preview.templateAep": "X:/shared_projects_2026/UNGO_VFX/production/working_files/UNG_VFXOVERLAY_SLATE_TEMPLATE.aep",
|
|
"preview.templateComp": "UNG_EXPORT_TEMPLATE",
|
|
"preview.overlayComp": "UNG_VFX_OVERLAY",
|
|
"preview.lutComp": "_SHOW LUT",
|
|
"preview.movTemplate": "4444 Tri",
|
|
"preview.mp4Template": "REVIEW_PREVIEW",
|
|
// Essential Property names on the NETFLIX_SLATE layer for the per-submission
|
|
// fields. If a name is wrong the build logs the template's actual property
|
|
// names as a warning, so it is a config fix rather than a code change.
|
|
"preview.slateScopeProp": "Scope",
|
|
"preview.slateSubmissionProp": "Notes",
|
|
} as const;
|
|
|
|
export type PipelineConfigKey = keyof typeof PIPELINE_CONFIG_DEFAULTS;
|
|
|
|
export async function getConfigValue(key: PipelineConfigKey): Promise<string> {
|
|
const row = await db.systemConfig.findUnique({ where: { key } });
|
|
return row?.value ?? String(PIPELINE_CONFIG_DEFAULTS[key]);
|
|
}
|
|
|
|
export async function getConfigNumber(key: PipelineConfigKey): Promise<number> {
|
|
const raw = await getConfigValue(key);
|
|
const n = Number(raw);
|
|
return Number.isFinite(n) ? n : Number(PIPELINE_CONFIG_DEFAULTS[key]);
|
|
}
|
|
|
|
export async function getConfigBoolean(key: PipelineConfigKey): Promise<boolean> {
|
|
const raw = (await getConfigValue(key)).trim().toLowerCase();
|
|
return raw === "true" || raw === "1" || raw === "yes";
|
|
}
|
|
|
|
/** Preview-stage settings handed to the worker inside the PREVIEW_ONLY manifest. */
|
|
export async function getPreviewConfig() {
|
|
const [
|
|
enabled, templateAep, templateComp, overlayComp, lutComp, movTemplate, mp4Template,
|
|
slateScopeProp, slateSubmissionProp,
|
|
] = await Promise.all([
|
|
getConfigBoolean("preview.enabled"),
|
|
getConfigValue("preview.templateAep"),
|
|
getConfigValue("preview.templateComp"),
|
|
getConfigValue("preview.overlayComp"),
|
|
getConfigValue("preview.lutComp"),
|
|
getConfigValue("preview.movTemplate"),
|
|
getConfigValue("preview.mp4Template"),
|
|
getConfigValue("preview.slateScopeProp"),
|
|
getConfigValue("preview.slateSubmissionProp"),
|
|
]);
|
|
return {
|
|
enabled, templateAep, templateComp, overlayComp, lutComp, movTemplate, mp4Template,
|
|
slateScopeProp, slateSubmissionProp,
|
|
};
|
|
}
|
|
|
|
/** Worker-facing config bundle returned by E6 registration. */
|
|
export async function getWorkerConfig() {
|
|
const [
|
|
pollSeconds, heartbeatSeconds, leaseSeconds, maxAttempts, stallTimeoutSeconds,
|
|
validationEnabled, validationSampleEvery, validationHandleFrames,
|
|
] = await Promise.all([
|
|
getConfigNumber("render.pollSeconds"),
|
|
getConfigNumber("render.heartbeatSeconds"),
|
|
getConfigNumber("render.leaseSeconds"),
|
|
getConfigNumber("render.maxAttempts"),
|
|
getConfigNumber("render.stallTimeoutSeconds"),
|
|
getConfigBoolean("validation.enabled"),
|
|
getConfigNumber("validation.sampleEvery"),
|
|
getConfigNumber("validation.handleFrames"),
|
|
]);
|
|
return {
|
|
pollSeconds, heartbeatSeconds, leaseSeconds, maxAttempts, stallTimeoutSeconds,
|
|
// Whether the validation stage runs is the server's call, so switching it
|
|
// off is a config change here rather than a redeploy of every worker (§8).
|
|
validationEnabled, validationSampleEvery, validationHandleFrames,
|
|
};
|
|
}
|