70cf45ead4
Deploy / deploy (push) Successful in 7m2s
Blender work is not a shot submission: no Export, no version, no validation, QC or delivery. It is "Ctrl+F12, but on the farm", so it is modelled as what it is — a queue entry and nothing more. That turned out to need very little. Claim, progress, fail and complete-render already tolerated a job with no Export behind them, so a Blender job reuses the whole lifecycle; RenderJob gains projectId, label and submittedBy so a job with no shot code still has something to show. Capability gating is new and was already missing: the claim now filters job types by the machine's reported tools. Without it a workstation without Blender would claim Blender work and fail it repeatedly, burning the attempts while a machine that could have rendered it sat idle. The worker asks for Blender jobs unconditionally and the server refuses them — trusting the worker to self-select would have left the same hole. The runner treats a clean exit with no saved frames as a failure: Blender exits 0 when a frame range is empty or an output path is unwritable, and a job that silently rendered nothing is the worst outcome available. Standalone jobs auto-requeue on a transient failure like any other work; delivery builds are deliberately excluded, since a half-written package wants a human first. Adds the Blender add-on (BlenderPanel/) and its docs. The add-on refuses to submit an unsaved file — the farm opens the .blend from disk, so unsaved changes would render the previous state without warning. Its payload is pinned by a contract test, since add-on and server only ever meet over JSON. Worker 1.5.0. Adds migration 20260815000000_blender_render_jobs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
2.0 KiB
C#
50 lines
2.0 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using VFXReviewWorker;
|
|
|
|
// VFXReview RenderWorker (RenderPipeline2 §7) — Windows service driving
|
|
// aerender.exe on artist workstations / render nodes. All state flows through
|
|
// /api/ext/* with API-key auth; the worker never touches the database.
|
|
//
|
|
// Run interactively for debugging: VFXReviewWorker.exe [path\to\config.json]
|
|
// Install as a service: see RenderWorker/README.md
|
|
|
|
// Dry-run the validation engine over an existing render folder. No server, no
|
|
// config, no queue — useful for checking work that predates the pipeline.
|
|
if (args.Any(a => a.Equals("--validate", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
return ValidateCommand.Run(args);
|
|
}
|
|
|
|
var configPath = args.FirstOrDefault(a => !a.StartsWith('-'));
|
|
|
|
// Install verification on a new machine — resolves paths, checks tools and
|
|
// pings the server, then exits. Never starts the service loop.
|
|
if (args.Any(a => a.Equals("--check", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
return await Preflight.RunAsync(configPath);
|
|
}
|
|
|
|
var options = WorkerOptions.Load(configPath);
|
|
|
|
// Positional args (config path) are consumed above and deliberately not
|
|
// forwarded — the command-line configuration provider rejects bare tokens.
|
|
var builder = Host.CreateApplicationBuilder();
|
|
builder.Services.AddWindowsService(o => o.ServiceName = "VFXReviewRenderWorker");
|
|
builder.Logging.AddProvider(new FileLoggerProvider());
|
|
|
|
builder.Services.AddSingleton(options);
|
|
builder.Services.AddSingleton<ApiClient>();
|
|
builder.Services.AddSingleton<ReportSpooler>();
|
|
builder.Services.AddSingleton<AerenderRunner>();
|
|
builder.Services.AddSingleton<PreviewStage>();
|
|
builder.Services.AddSingleton<ValidationStage>();
|
|
builder.Services.AddSingleton<DeliveryStage>();
|
|
builder.Services.AddSingleton<BlenderRunner>();
|
|
builder.Services.AddSingleton<JobExecutor>();
|
|
builder.Services.AddHostedService<WorkerService>();
|
|
|
|
await builder.Build().RunAsync();
|
|
return 0;
|