{"id":50831511,"url":"https://github.com/loonghao/renderacre","last_synced_at":"2026-06-13T23:32:55.751Z","repository":{"id":360713171,"uuid":"1251378384","full_name":"loonghao/renderacre","owner":"loonghao","description":"Rust render-farm controller, worker, OpenJD, and Python ABI3 toolkit for DCC pipelines.","archived":false,"fork":false,"pushed_at":"2026-05-27T16:10:17.000Z","size":77,"stargazers_count":0,"open_issues_count":11,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-27T16:15:53.443Z","etag":null,"topics":["blender","dcc","maturin","maya","openjd","pyo3","render-farm","renderfarm","rust"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/renderacre/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loonghao.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-27T14:15:56.000Z","updated_at":"2026-05-27T16:10:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/loonghao/renderacre","commit_stats":null,"previous_names":["loonghao/renderacre"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/loonghao/renderacre","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loonghao%2Frenderacre","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loonghao%2Frenderacre/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loonghao%2Frenderacre/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loonghao%2Frenderacre/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loonghao","download_url":"https://codeload.github.com/loonghao/renderacre/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loonghao%2Frenderacre/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34304629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blender","dcc","maturin","maya","openjd","pyo3","render-farm","renderfarm","rust"],"created_at":"2026-06-13T23:32:53.571Z","updated_at":"2026-06-13T23:32:55.746Z","avatar_url":"https://github.com/loonghao.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Renderacre\n\n[![CI](https://github.com/loonghao/renderacre/actions/workflows/ci.yml/badge.svg)](https://github.com/loonghao/renderacre/actions/workflows/ci.yml)\n[![DCC E2E](https://github.com/loonghao/renderacre/actions/workflows/dcc-e2e.yml/badge.svg)](https://github.com/loonghao/renderacre/actions/workflows/dcc-e2e.yml)\n[![Release](https://github.com/loonghao/renderacre/actions/workflows/release.yml/badge.svg)](https://github.com/loonghao/renderacre/actions/workflows/release.yml)\n[![GitHub Release](https://img.shields.io/github/v/release/loonghao/renderacre?label=github%20release)](https://github.com/loonghao/renderacre/releases)\n[![PyPI](https://img.shields.io/pypi/v/renderacre.svg)](https://pypi.org/project/renderacre/)\n[![Python](https://img.shields.io/pypi/pyversions/renderacre.svg)](https://pypi.org/project/renderacre/)\n[![Downloads](https://static.pepy.tech/badge/renderacre)](https://pepy.tech/project/renderacre)\n[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE)\n\nRenderacre is a Rust render-farm foundation inspired by Deadline: a remote controller API, standalone workers, Python submitter bindings, and Open Job Description (OpenJD) job templates for portable DCC and batch workloads.\n\nThe Python package is named `renderacre` and is built as a `cp37-abi3` wheel, so one wheel supports CPython 3.7 and newer on each platform.\n\n## Installation\n\nInstall the Python submitter API from PyPI:\n\n```bash\npython -m pip install renderacre\n```\n\nThe published wheels use `cp37-abi3`, which means each platform wheel supports CPython 3.7 and newer.\n\nInstall the standalone controller and worker binaries from GitHub Releases.\n\nLinux/macOS:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/loonghao/renderacre/main/scripts/install.sh | bash\n```\n\nWindows PowerShell:\n\n```powershell\niwr https://raw.githubusercontent.com/loonghao/renderacre/main/scripts/install.ps1 -UseB | iex\n```\n\nPin a release or install directory when deploying render nodes:\n\n```bash\nexport RENDERACRE_VERSION=v0.1.4\nexport RENDERACRE_INSTALL_DIR=/opt/renderacre/bin\ncurl -fsSL https://raw.githubusercontent.com/loonghao/renderacre/main/scripts/install.sh | bash\n```\n\n```powershell\n$env:RENDERACRE_VERSION = \"v0.1.4\"\n$env:RENDERACRE_INSTALL_DIR = \"$env:LOCALAPPDATA\\renderacre\\bin\"\niwr https://raw.githubusercontent.com/loonghao/renderacre/main/scripts/install.ps1 -UseB | iex\n```\n\nAfter installation, run the farm processes:\n\n```bash\nrenderacre-controller --bind 0.0.0.0:7878\nrenderacre-worker --controller http://controller-host:7878 --name render-node-01 --label app=blender\n```\n\nFor source builds:\n\n```bash\ncargo install --path crates/farm-controller --locked\ncargo install --path crates/farm-worker --locked\n```\n\n## Features\n\n- Rust HTTP controller with job submission, worker registration, leasing, retries, task dependencies, and job state inspection.\n- Standalone worker binary that executes direct commands or OpenJD runtime payloads.\n- Controller-collected worker logs, controller events, task stdout/stderr tails, downloadable task artifacts, and upstream/downstream task dependency tracking.\n- Official `openjd-model` validation and job creation for OpenJD `jobtemplate-2023-09`.\n- Official `openjd-sessions` execution for OpenJD step scripts, task parameters, environments, embedded files, progress/status callbacks, and OpenJD stdout directives.\n- OpenJD `hostRequirements` routing through worker capabilities such as `attr.worker.os.family`, `attr.worker.cpu.arch`, and `amount.worker.vcpu`.\n- PyO3/maturin Python module for pipeline submitters and DCC tools.\n- CI for fmt, clippy, unit tests, controller/worker e2e smoke, and ABI3 wheel builds.\n- Release workflow for cross-platform wheels, sdist, and PyPI Trusted Publishing.\n\n## Local Development\n\n```powershell\ncargo test --workspace\ncargo clippy --workspace --all-targets -- -D warnings\npowershell -NoProfile -ExecutionPolicy Bypass -File .\\scripts\\e2e_smoke.ps1\npython .\\scripts\\e2e_dcc_tasks.py --jobs python,command\npython -m maturin build --release -o target\\wheels\n```\n\nThe wheel filename should contain `cp37-abi3`, for example:\n\n```text\nrenderacre-0.1.4-cp37-abi3-win_amd64.whl\n```\n\n## Run a Local Farm\n\nStart the controller:\n\n```powershell\ncargo run -p renderacre-controller -- --bind 127.0.0.1:7878\n```\n\nThe controller defaults to the in-memory scheduler for demos and tests. Use the\nSQLite backend for a lightweight durable farm:\n\n```powershell\ncargo run -p renderacre-controller -- --storage sqlite --sqlite-path .\\renderacre.sqlite3\n```\n\nStart a worker:\n\n```powershell\ncargo run -p renderacre-worker -- --controller http://127.0.0.1:7878 --name local-worker --label os=windows\n```\n\nUse `--slots \u003ccount\u003e` for a worker that can execute multiple compatible tasks\nconcurrently. The controller will not lease more active tasks to that worker\nthan its registered slot capacity.\n\nSubmit a direct command job:\n\n```powershell\nInvoke-RestMethod `\n  -Method Post `\n  -Uri http://127.0.0.1:7878/v1/jobs `\n  -ContentType application/json `\n  -InFile .\\examples\\hello_job.json\n```\n\nTasks can optionally declare routing requirements without changing older job\npayloads:\n\n```json\n{\n  \"name\": \"maya-render\",\n  \"command\": { \"executable\": \"mayapy\", \"args\": [\"render.py\"] },\n  \"requirements\": {\n    \"labels\": { \"os\": \"windows\", \"app\": \"maya\" },\n    \"pools\": [\"lighting\"],\n    \"amounts\": [{ \"name\": \"amount.worker.vcpu\", \"min\": 2 }],\n    \"attributes\": [\n      { \"name\": \"attr.worker.os.family\", \"anyOf\": [\"windows\"] }\n    ]\n  }\n}\n```\n\nWorkers advertise matching capabilities with labels such as\n`--label os=windows --label app=maya --label pool=lighting`. Renderacre workers\nalso register default OpenJD capabilities for OS family, CPU architecture, and\nslot count, so OpenJD `hostRequirements` work out of the box for common cases.\n\nOperators can define shared limits for scarce licenses or farm-wide resources,\nthen tasks can declare the named limits they need:\n\n```text\nPOST /v1/limits\nGET /v1/limits\n```\n\n```json\n{\n  \"name\": \"maya-render\",\n  \"command\": { \"executable\": \"mayapy\", \"args\": [\"render.py\"] },\n  \"limits\": [\"maya\"]\n}\n```\n\nCommon queue operations are available as stable action endpoints:\n\n```text\nPOST /v1/jobs/{job_id}/pause\nPOST /v1/jobs/{job_id}/resume\nPOST /v1/jobs/{job_id}/cancel\nPOST /v1/jobs/{job_id}/priority\nPOST /v1/tasks/{task_id}/cancel\nPOST /v1/tasks/{task_id}/requeue\n```\n\n## Python Submitter API\n\nInstall a local build:\n\n```powershell\npython -m pip install maturin\npython -m maturin develop\n```\n\nSubmit a command job:\n\n```python\nimport renderacre\n\njob_json = renderacre.command_job(\n    \"hello-from-python\",\n    \"python\",\n    [\"-c\", \"print('hello from renderacre')\"],\n)\nprint(renderacre.submit_job(\"http://127.0.0.1:7878\", job_json))\n```\n\nSubmit an OpenJD template:\n\n```python\nimport json\nimport renderacre\n\ntemplate = open(\"examples/openjd_python_frames.yaml\", encoding=\"utf-8\").read()\njob_json = renderacre.openjd_job(\n    \"openjd-demo\",\n    template,\n    json.dumps({\"Message\": \"hello through OpenJD\"}),\n)\nprint(renderacre.submit_job(\"http://127.0.0.1:7878\", job_json))\n```\n\n## OpenJD Support\n\nRenderacre accepts an OpenJD job template under `openjd.template_yaml`.\n\nThe controller:\n\n1. Parses YAML/JSON with the official OpenJD parser.\n2. Validates the template and enabled extensions.\n3. Preprocesses typed job parameters, including `PATH` values.\n4. Creates the resolved OpenJD job model.\n5. Expands step parameter spaces into farm tasks.\n6. Preserves OpenJD `hostRequirements` as scheduler requirements.\n\nThe worker:\n\n1. Creates an OpenJD session.\n2. Enters job and step environments.\n3. Runs each OpenJD task through `openjd-sessions`.\n4. Streams OpenJD action status/progress callbacks and captures stdout/stderr.\n5. Exits environments and cleans the session directory.\n\nSupported current extensions default to all extensions known by `openjd-model`: `EXPR`, `FEATURE_BUNDLE_1`, `TASK_CHUNKING`, and `REDACTED_ENV_VARS`.\n\nFor a routing-focused example, see `examples/openjd_host_requirements.yaml`.\n\n## Dashboard\n\nRenderacre includes a Vite + React dashboard under `dashboard/`. It uses modular React components, compact queue tables, worker status panels, per-worker live logs, an OpenJD task inspector, React Flow dependency graphs, downloadable artifacts, and stdout/stderr tail views.\n\n![Renderacre dashboard queue preview](docs/images/renderacre-dashboard.png)\n\nRun it during development:\n\n```powershell\ncargo run -p renderacre-controller -- --bind 127.0.0.1:7878\ncd dashboard\nnpm ci\nnpm run dev\n```\n\nThe Vite dev server proxies `/v1` and `/healthz` to the controller. For a deployed dashboard:\n\n```powershell\ncd dashboard\nnpm run build\n```\n\nServe `dashboard/dist` through the controller with `--dashboard-dir dashboard/dist`, or through your internal web server or reverse proxy next to the controller API.\n\n## Command and DCC Examples\n\nRenderacre can run any executable the worker can spawn: `cmd.exe`, PowerShell,\n`pwsh`, `bash`, `sh`, Blender, Maya, `ffmpeg`, ImageMagick, studio launchers, or\nyour own tools. Generic command frames are the quickest local test because they\nsubmit three frame tasks per shell, write one text artifact per frame, echo the\nartifact path with `RENDERACRE_ARTIFACT=...`, and verify the worker logs plus the\ndownload API.\n\nRun command frame tests against the shells available on the current machine:\n\n```powershell\npython .\\scripts\\e2e_dcc_tasks.py --jobs command --shells auto\n```\n\nPin specific shell runners when testing Windows and POSIX wrapper behavior:\n\n```powershell\npython .\\scripts\\e2e_dcc_tasks.py --jobs command --shells cmd,powershell,bash\n```\n\nFrame outputs are written under\n`target/e2e-dcc/command-frames/\u003cshell\u003e/*_frame_0001.txt` and uploaded by CI as\n`command-frame-artifacts`.\n\nRenderacre also ships real OpenJD examples for Python frame tasks, Blender\nbackground renders, and Maya standalone scene exports. The same templates are\nexercised by the `DCC E2E` GitHub Actions workflow: the generic command job uses\nthe runner shells, Blender uses official Linux tarballs, and Maya uses the\n`tahv/mayapy` container images.\n\nRun the full DCC e2e suite on a machine that has Blender and Maya on `PATH`:\n\n```powershell\npython .\\scripts\\e2e_dcc_tasks.py --jobs all --blender-exe blender --maya-python mayapy\n```\n\nRun only the jobs available on the current machine:\n\n```powershell\npython .\\scripts\\e2e_dcc_tasks.py --jobs auto\n```\n\nBlender:\n\n```powershell\n$template = Get-Content .\\examples\\dcc\\blender_render_openjd.yaml -Raw\n$params = @{\n  BlenderExecutable = \"blender\"\n  ScriptPath = (Resolve-Path .\\examples\\dcc\\blender_render_task.py).Path\n  OutputDir = (Join-Path (Get-Location) \"renders\\blender\")\n} | ConvertTo-Json\n```\n\nMaya:\n\n```powershell\n$template = Get-Content .\\examples\\dcc\\maya_render_openjd.yaml -Raw\n$params = @{\n  MayaPython = \"mayapy\"\n  ScriptPath = (Resolve-Path .\\examples\\dcc\\maya_render_task.py).Path\n  OutputDir = (Join-Path (Get-Location) \"renders\\maya\")\n} | ConvertTo-Json\n```\n\nPass the template and parameter JSON through `renderacre.openjd_job(...)` or submit the equivalent REST payload to `/v1/jobs`.\n\nFor CI parity, the script writes command `.txt` frames, Blender PNGs, and Maya\n`.ma` scenes under `target/e2e-dcc/` and fails if any expected frame output,\nartifact download, or worker log line is missing.\n\n## Deployment\n\nRecommended first deployment shape:\n\n- Run one controller per farm or queue: `renderacre-controller --config deploy/lightweight/controller.yaml`.\n- Run one worker process per render node: `renderacre-worker --controller http://controller-host:7878 --name \u003cnode-name\u003e --label app=blender`.\n- Put the controller behind a private network or authenticated reverse proxy.\n- Keep render executables and scripts on shared storage, then pass `PATH` parameters through OpenJD.\n- Use GitHub Releases or PyPI to distribute the `renderacre` wheel to submitter machines.\n\nSQLite is the default durable profile for small deployments. Start the\ncontroller with `--storage sqlite --sqlite-path \u003cpath\u003e` or set\n`RFARM_STORAGE=sqlite` and `RFARM_SQLITE_PATH`. Use `--dashboard-dir \u003cpath\u003e` or\n`RFARM_DASHBOARD_DIR` to serve a built dashboard from the controller in the\nsingle-node profile. The scheduler API remains the same for REST workers,\ndashboard reads, and Python submitters; future Postgres or managed/cloud storage\nbackends can replace the same storage boundary without changing submitter\ncontracts.\n\nCloud-ready backend, artifact, worker identity, and scheduler extension\ncontracts are documented in\n[docs/extension-contracts.md](docs/extension-contracts.md).\nThe one-command lightweight profile, service examples, and upgrade/backup\nguidance are documented in [docs/deployment.md](docs/deployment.md).\n\n## Release\n\nThe release workflow builds Linux, Windows, and macOS wheels plus an sdist. PyPI publishing uses Trusted Publishing through the `pypi` GitHub environment.\nIt also uploads standalone controller/worker archives to GitHub Releases for Linux, macOS, and Windows.\n\nManual release dry run:\n\n```powershell\npython -m maturin build --release -o dist\npython -m pip install twine\npython -m twine check dist/*\n```\n\nPublish from GitHub:\n\n1. Configure PyPI Trusted Publisher for `loonghao/renderacre`, workflow `release.yml`, environment `pypi`.\n2. Push a `vX.Y.Z` tag or publish a GitHub Release.\n3. The workflow uploads artifacts to PyPI when the publish gate is active.\n\nSee [docs/architecture.md](docs/architecture.md) for the internal layout.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floonghao%2Frenderacre","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floonghao%2Frenderacre","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floonghao%2Frenderacre/lists"}