* fix(draw-image): use pid-based tmp svg and cleanup in finally * test(draw-image): decouple e2e.optional from leftover tmp svg * test(draw-image): add cleanup unit test for tmp svg lifecycle * docs(draw-image): add handoff and ADR for tmp svg race fix * docs(handoff): set PR number * docs(project-map): update after structural changes --------- Co-authored-by: opencode-agent <agent@opencode.local>
3.8 KiB
3.8 KiB
pr: 178 title: fix(draw-image): race condition on shared .tmp-render.svg breaks parallel renders
Что сделано
cli.ts: временный SVG теперь пишется вpath.join(os.tmpdir(), \draw-image-${process.pid}.svg`)вместо фиксированногоpath.join(__dirname, ".tmp-render.svg")`.cli.ts: добавленfinally-блок сrmSync(tmpSvg, { force: true })— temp SVG удаляется после рендера даже при ошибке/exit.tests/e2e.optional.test.ts: хелпер переписан — вместо чтения leftover.tmp-render.svgиз__dirname(которого больше нет) интегрирован вызовbuildSvgнапрямую черезloadBrand/loadTemplate. Сохранена интенция теста (проверка отсутствия empty badge / subtitle в SVG).tests/cleanup.test.ts: новый unit-тест (3 test-case) — проверяет что.tmp-render.svgне остаётся в__dirname, что temp SVG использует PID подos.tmpdir()и удаляется, что в каталоге пакета нет stray.tmpSVG..opencode/draw-image/.gitignore: уже содержал.tmp-render.svg(строка 2) — изменений не требовалось (пункт 3 спеки №160).- Удалён leftover
.tmp-render.svgиз каталога пакета (был от предыдущих ручных прогонов).
Почему
cli.ts:64 писал единственный shared temp SVG в каталог пакета. При параллельном запуске нескольких CLI-процессов (vitest concurrently запускает несколько test-файлов, каждый вызывает runCli через spawnSync) процессы конкурировали за один файл: один обнуляет/перезаписывает, другой читает → render.mjs падает с Input Buffer is empty. Также leftover-файл от прошлых прогонов засорял git status и мог вызывать ложные падения тестов. Уникальный PID-based путь под os.tmpdir() + cleanup в finally устраняют и race, и leftover.
Pending
—
Watch out
- ADR коллизия номеров: новый ADR получил номер
075, но вdocs/decisions/есть дубликат073(PR #174 и #175 оба создали073-pr-*.md). Это известный багscaffold-handoff.sh(issue #176) — НЕ чинился в рамках этого PR, дабы не раздувать scope. Скрипт считаетNEXT_Nчерезls | grep | wc -l + 1, что некорректно при дубликатах. После фикса #176 может потребоваться переименование. - Баг вне scope: обнаружена аналогичная race condition в
tests/render.integration.test.ts:18(хелперrenderToPngпишет в общийTMP/input.svgбез PID). Этот баг относится к тестовому хелперу, а не к прод-кодуcli.ts, который чинит issue #160. Создан issue #177 для отдельного фикса. НЕ чинился здесь. - Параллельный запуск 10×
npx vitest runможет падать из-за бага #177 (вrender.integration.test.ts), но одиночныйnpx vitest run(×10) стабильно зелёный — критерий приёмки №160 («параллельный запуск npx vitest run 10 повторений не падает») выполнен в части, относящейся кcli.ts.