Расчётные движки: выбор и настройка

> Кратко. Движок, профиль и ядро расчёта задаются переменными окружения службы воркера. Значения по умолчанию в коде — самые осторожные: старый sety, профиль legacy, ядро на Python. Прод работает на heatnet, профиле fixed и ядре Rust, и это нужно задать явно.

Читаю как

Чем движки и профили отличаются для пользователя, описано на странице Расчётный движок: heatnet и отличия от десктопа. Здесь — только настройка сервера.

Переменные воркера

Переменная Значения По умолчанию в коде Прод
SETY_ENGINE legacy — sety/ww.py; heatnet — python -m heatnet.cli legacy heatnet
HEATNET_PROFILE legacy — побайтно как sety; fixed — с исправлениями legacy fixed
HEATNET_CORE python; rust — тяжёлые части считает ядро; check — считают оба, берётся Python, расхождения пишутся в stderr python rust
HEATNET_QUIRKS_OFF имена особенностей sety (compat.Quirk) через запятую — выключить сверх профиля пусто не задаётся
HEATNET_WRITE insert — писать строки *_out прежним INSERT вместо COPY (сверка, аварийный откат) COPY не задаётся
HEATNET_CORE_STATS любое значение — итог работы ядра в stderr выкл. не задаётся
SETY_TIMEOUT_S предел одного расчёта, с 3600 —
CALC_PROTOCOL_KEEP_DAYS сколько дней хранить протоколы расчётов 365 —

Неизвестное значение SETY_ENGINE, HEATNET_PROFILE или имя в HEATNET_QUIRKS_OFF — ошибка запуска расчёта с текстом «допустимо …». Неизвестное HEATNET_CORE молча считается python.

Где задаются и когда действуют

  • Переменные службы воркера (в Windows — параметры службы NSSM, AppEnvironmentExtra) важнее файла .env: .env дополняет окружение, но не перекрывает его.
  • Расчёт идёт отдельным процессом, который получает окружение воркера. Новое значение переменной вступает в силу после перезапуска службы воркера. Перезапускайте мягко: команда shutdown через брокер, воркер дорабатывает текущий расчёт и выходит, а NSSM поднимает его снова. Перезапуск службы средствами NSSM обрывает идущий расчёт.
  • Новый код heatnet (heatnet/) подхватывается без перезапуска: каждый расчёт — новый процесс Python. Изменения worker.py требуют перезапуска воркера.
  • Все воркеры, которые слушают очередь одного города, должны иметь одинаковые настройки. Иначе результат зависит от того, какой воркер взял задачу.
  • В протоколе расчёта движок и профиль не записываются. Какой профиль считал, видно только по переменным службы.

Ядро на Rust

  • Исходники — native/heatnet_core (сборка maturin, модуль heatnet._core). На сервере это файл heatnet/_core.pyd рядом с кодом heatnet. В git он не хранится и выкатывается отдельно, под свой коммит.
  • Если модуля нет или он не загрузился, расчёт идёт на Python с теми же числами. В stderr процесса появляется одна строка «ядро не загружено … — расчёт на Python».
  • Работающий расчёт держит файл модуля открытым. Перед заменой его переименовывают (Windows это разрешает), а не перезаписывают.
  • Проверка нового ядра — HEATNET_CORE=check на копии базы: оба пути считают, расхождения пишутся в stderr.

Другие очереди и движки

  • Теплопотери и износ идут через тех же воркеров. Отдельную очередь можно задать в HEAT_LOSSES_QUEUE; в режиме нескольких городов к ней добавляется .<код>. Без переменной задача идёт в очередь города tgid.<код>, а у API одного города — в очередь Celery по умолчанию (celery).
  • Фоновые выгрузки — FILE_JOBS_QUEUE, запекание статичных тайлов — STATIC_TILES_QUEUE, по тому же правилу.
  • Водопровод считает отдельная служба water_engine со своей средой Python (WNTR/EPANET): uvicorn water_engine.service:app --host 127.0.0.1 --port 8070. API ходит в неё по WATER_ENGINE_URL (по умолчанию http://127.0.0.1:8070) с тем же секретом WATER_ENGINE_TOKEN. Без секрета служба принимает любые запросы, поэтому слушать она должна только 127.0.0.1 или внутреннюю сеть. Доступность движка показывает GET /api/v1/water/status.

Для разработчика

  • Выбор команды расчёта — worker._engine_cmd(), окружение процесса — worker._run_process() (добавляет HEATNET_PROGRESS=stderr для строки хода расчёта и HEATNET_PROTOCOL_JSON для JSON-протокола).
  • Профили — heatnet/compat.py (Quirks.from_env), ядро — heatnet/native.py, запись результатов — heatnet/io/writer.py.
  • Сверка движков и эталоны — scripts/golden/engine_parity.py, scripts/golden/run_reference.py; замеры — scripts/golden/bench_heatnet.py.
Хотите увидеть эту функцию на своих данных?Покажем ТГИД на демонстрации и ответим на вопросы инженеров.
Запросить демо