# Build173 — снижение нагрузки онлайн-обновлений Версия: 2026.09.29.10. ## Установка Архив устанавливается поверх build171 или build172. Включены предыдущие изменения build172: ночное обновление КХЛ, отчёт и повтор неудачных записей. Если build172 ещё не установлен, отдельно устанавливать его перед этим архивом не нужно. В пакете 6 рабочих файлов с сохранением структуры папок и эта инструкция: - app.py; - hockey_data/service.py; - khl_site/khl_data_center.py; - khl_site/khl_site_collector.py; - khl_site/update_runtime.py; - khl_site/web/index.html. Непосредственно оптимизация build173 меняет app.py и hockey_data/service.py. Остальные четыре файла включены из build172 для установки одним пакетом. Остановите приложение, замените все перечисленные файлы и запустите приложение. Обновите страницу браузера через Ctrl+F5. Для стандартной Linux-службы после замены файлов: `sudo systemctl restart khl-data.service`. Если у службы другое имя, используйте его. На Windows перезапустите процесс приложения обычным способом. Проверить версию можно по /api/health: поле build должно быть 2026.09.29.10. Изменения схемы БД и дополнительные зависимости не требуются. Пользовательские JSON-настройки, .env, база данных и архивы КХЛ в пакет не включены. ## Что исправлено в онлайн-обновлениях Stat2TV Раньше любое изменение JSON матча запускало повторное сохранение всего справочника турнира. Даже при неизменившихся профилях обновлялось время синхронизации каждого игрока, его участия в турнире и сезонной статистики. На 1 000 профилей это означало около 6 000 SQL-вызовов только на повторное сохранение справочника. Теперь: - разобранные справочники игроков, тренеров, стран и судей используются повторно; - тяжёлый разбор справочников выполняется в рабочем потоке, не блокируя основной цикл HTTP-сервера; - записи сравниваются с последним успешно сохранённым состоянием по содержимому; неизменившиеся профили не перезаписываются; - изменение одного профиля вызывает запись этого профиля, без повторного сохранения остальных участников турнира; - изменения стран также учитываются; составы, события, счёт и статистика самого матча продолжают обновляться; - одновременно пришедшие запросы одного матча используют одну синхронизацию, включая запросы на русском и английском языках; - готовый результат общей синхронизации доступен другим браузерам 0,75 секунды. Ошибочный результат не используется для следующей попытки; - одновременные запросы одного справочника объединяются в одну загрузку; - для сравнения старого и нового счёта больше не собирается полная карточка матча второй раз; - если один браузер закрылся, общая синхронизация другого браузера продолжает работу; - после ошибки транзакции новое состояние справочника не считается сохранённым: следующая попытка снова выполняет необходимые записи. Период получения свежих справочников из Stat2TV остаётся заданным настройкой match_directories_cache_seconds, по умолчанию 300 секунд. Эта настройка относится к справочникам; основной онлайн-опрос матча продолжает использовать прежний интервал. Кэш разобранных справочников ограничен 8 наборами, сохранённых контрольных состояний — 16 турнирами, готовых онлайн-результатов — 32 матчами. Ответы на исторические запросы с нулевым сроком кэширования по-прежнему не сохраняются в кэше ресурсов. Первая загрузка нового турнира или загрузка после перезапуска приложения остаётся полной. Основное снижение нагрузки получено на повторных онлайн-обновлениях. Поле synced_at у неизменившегося профиля больше не переписывается каждую секунду; отметка обновления карточки матча продолжает обновляться. ## Измерение до и после Одинаковая локальная проверка старого и нового кода: справочник из 1 000 игроков, 44 игрока в составах матча, изменение счёта на каждом цикле. Первичная загрузка выполнена до измерения. Три повторных онлайн-обновления, ниже медианные значения. | Показатель на одно обновление | До исправления | После исправления | |---|---:|---:| | SQL-вызовы | 6 132 | 121 | | CPU-время процесса | 1 097,65 мс | 30,99 мс | В этом тесте число SQL-вызовов снизилось на 98,0%, CPU-время — на 97,2%. Это изолированный тест с локальной SQLite и имитацией ответов Stat2TV, а не замер вашего сервера. Сетевые задержки и работа PostgreSQL в измерение не включены. Результат показывает сокращение работы конкретного пути обновления; он не означает, что общая загрузка вашего сервера гарантированно снизится со 100% до 3%. Фоновая синхронизация расписаний, SQL-источники Mapping и первичные импорты остаются отдельными источниками нагрузки. После установки нужно сравнить фактическую нагрузку при тех же матчах и числе открытых браузеров. ## Включённые функции КХЛ из build172 - один поток загрузки, пауза перед сетевыми запросами 0,5 секунды; - полное обновление КХЛ ежедневно в 03:00 по Москве, без открытого браузера; - защита от одновременного ручного и ночного запуска; - сохранение даты ночного запуска, отчёта и очереди неудачных записей после перезапуска; - кнопка «Отчёт обновлений» во вкладке «КХЛ сайт»: время, длительность, результаты, ошибки и импорт в БД; - кнопка «Повторить неудачные»: повтор только карточек из очереди; если не прочитан список участников, он перечитывается с пропуском успешно обновлённых карточек; - прежние данные при ошибках загрузки сохраняются; - если загрузка файлов прошла, а импорт в БД завершился ошибкой, возможен повтор только импорта без обращения к КХЛ; - отчёт можно скачать, он содержит полную очередь ошибок; на экране показываются первые 50. Расписание проверяется каждые 30 секунд. В течение 03:00–03:59 пропущенный запуск допускается, если сегодня он ещё не запускался. Если сервер всё это время был выключен или другое обновление занимало всё окно, днём полная загрузка не запускается — следующая попытка следующей ночью. Ошибки не вызывают бесконечных автоматических повторов; кнопка повтора доступна администратору. При первом запуске создаётся settings/local/khl_updates.json, если его ещё нет: ```json { "enabled": true, "time": "03:00", "workers": 1, "request_delay_seconds": 0.5, "window_minutes": 60 } ``` Время московское независимо от часового пояса ОС. Изменение настроек применяется к следующим запускам; уже выполняющуюся загрузку это не прерывает. Рабочие файлы создаются на сервере и не поставляются в архиве: - settings/local/khl_update_state.json — состояние и последний отчёт; - settings/local/khl_update_state.lock — блокировка задания; - khl_site/data/khl_update_pending.json — очередь повтора; - khl_site/data/khl_update_report.json — диагностика загрузчика; - прежние khl_site/data/khl_*_all.json — данные. ## Проверка 12 новых сценариев проверяют пропуск неизменившихся записей, обновление одного профиля, откат транзакции, восстановление источника, изменение страны, защиту общих данных от изменений другим матчем, русский/английский ответы, отмену запроса браузером, повтор после ошибки, ограничения кэша, одновременные матчи и ручной импорт. Вместе с регрессионными проверками карточки матча, нормализованной статистики, открытия матча и производительности: 42 успешные проверки. Два старых текстовых теста интерфейса, требующих уже удалённую ранее переменную cachedRostersReady, исключены; они не относятся к этому изменению. Синтаксис Python проверен. Реальные PostgreSQL, Stat2TV, vMix и сервер пользователя в этих проверках не использовались. После установки подтвердите результат по фактической загрузке CPU и работе онлайн-матча.