# ADR-075: Race condition on shared .tmp-render.svg breaks parallel renders ## Статус Accepted (2026-07-31) ## Контекст `cli.ts` рендерил SVG-обложки через двухфазный процесс: 1. `writeFileSync(path.join(__dirname, ".tmp-render.svg"), svg)` — запись в единственный fixed-path файл в каталоге пакета. 2. `spawnSync("node", ["render.mjs", tmpSvg, outPath])` — дочерний процесс читает файл и рендерит PNG через sharp. При параллельном запуске нескольких CLI-процессов (vitest concurrently запускает несколько test-файлов, каждый вызывает `runCli` через `spawnSync`) процессы разделяли один `.tmp-render.svg`: один процесс обнулял/перезаписывал файл, пока другой его читал → `render.mjs` падал с `Input Buffer is empty` (пустой буфер SVG). Дополнительно leftover `.tmp-render.svg` от прошлых ручных прогонов засорял `git status` и мог содержать неактуальный SVG, вызывая ложные падения тестов. ## Решение Использовать уникальный temp-файл с PID в имени под системным `os.tmpdir()`: ```ts const tmpSvg = path.join(os.tmpdir(), `draw-image-${process.pid}.svg`) ``` и удалять его в `finally`-блоке после рендера (cleanup гарантирован даже при `process.exit(1)`). `render.mjs` не изменён — он уже принимает path к SVG как argv, уникальность обеспечивает `cli.ts`. `.gitignore` уже содержал `.tmp-render.svg` для обратной совместимости. ## Альтернативы - **Передача SVG через stdin в `render.mjs`**: избегает temp-файла целиком, но требует переписывания `render.mjs` (чтение из stdin вместо `readFileSync(argv)`), что выходит за рамки спеки #160 и ломает контракт «`render.mjs` принимает path как argv». - **Уникальный temp-каталог на процесс вместо PID-суффикса**: `fs.mkdtempSync(path.join(os.tmpdir(), "draw-image-"))` — даёт больше изоляции, но избыточен для одного SVG-файла; PID-суффикс достаточен, т.к. `spawnSync` синхронный и один процесс не запускает два рендера одновременно. - **Atomic write (write-rename)**: `writeFileSync(tmp + ".part")` + `rename(tmp + ".part", tmp)` — не решает race (два процесса всё равно пишут в один путь), нужен уникальный путь.