perf(factory): тёплый пул процессов WeasyPrint вместо exec-per-doc #100
Reference in New Issue
Block a user
Delete Branch "perf/factory-weasyprint-warm-pool"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Проблема
Генерация PDF в
factoryспавнила новый процессweasyprintна каждый документ (execвServices/Generator/index.ts). Медленные 3-5 сек — холодный старт Python: import всего стека (cffi/pydyf/tinycss2/Pango/cairo/HarfBuzz) + скан fontconfig. Сам рендер быстрый (<0.5 сек), но старт платился каждый раз — процесс умирал сразу после генерации.Решение
Тёплый пул из N долгоживущих Python-процессов (
WeasyPool/WeasyWorker):WEASY_POOL_SIZE(дефолтmin(4, CPU)) → реальный параллелизм, одновременные генерации не сериализуются к одному процессу (FIFO-очередь ожидающих);/venv(controller/Dockerfile), фоллбэкpython3;pendingреджектится, следующий вызов поднимает процесс заново.Протокол: в stdin воркера пишем
<htmlPath>\t<pdfPath>, читаемOK/ERR <traceback>. PDF не гоним через пайп — обмениваемся путями к временным файлам.Детерминизм
Сохранён:
SOURCE_DATE_EPOCH=0в env воркера. Заодно выровнялweasyPrintVersion62.3→67(синхрон сpip install WeasyPrint==67вcontroller/Dockerfile— метадата producer'а документов больше не врёт о версии).Эффект
10 одновременных генераций при пуле 4: ~3 волны по <0.5 сек (~1.5 сек у последнего) против ~30-50 сек в старой схеме (10× холодный старт).
Проверки
tsc --noEmit— чистоunbuild— exit 0В playbooks менять нечего — прод тянет готовые coopback-образы, питон+weasyprint в
/venvуже есть; dist пересобирается штатно (pnpm -F @coopenomics/factory build).🤖 Generated with Claude Code