Files
ayurishchevandClaude Opus 5.5 0bda0038d0 Остаток п. 9 ревью: синхронная БД вне event loop, повторное ревью
Повторное ревью кодовой базы: docs/reviews/2026-09-28-1243-codebase-review.md
(статус 12 замечаний, новые замечания 13–16).

Остаток п. 9 (docs/changes/022):
- 14 async-функций API, UI и сервисов больше не обращаются к SQLite
  напрямую — через asyncio.to_thread; jobs.start_jobs стал async (БД в
  потоке, create_task в event loop); ops._conn для подключения к устройству;
- тест-линтер по AST: в async def нет прямых вызовов функций с
  session_scope — защита от регресса.

Тесты: 29 из 29. Стенд: задачи и актор событий в порядке, параллельные
запросы не ждут медленного устройства, боевые данные не изменены.
Ручная проверка UI пользователем на момент коммита не подтверждена.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:12:44 +03:00

3.1 KiB
Raw Permalink Blame History

Итоги: 022 — остаток п. 9: синхронная БД в async-коде

Источник — ревью docs/reviews/2026-09-28-1243-codebase-review.md, п. 9 (частично закрыт в 019).

Сделано

  • Разведка по AST нашла 14 async-функций с прямыми синхронными обращениями к SQLite (в ревью были названы 2) — все переведены на asyncio.to_thread; исключение — lifespan (выполняется до приёма запросов).
  • jobs.start_jobs — async: БД и события job.created — синхронная _create_jobs в потоке, create_task — в event loop; все вызовы с await.
  • ops._conn — чтение устройства и расшифровка пароля в потоке во всех операциях (опрос, бэкап, канал, обновления ROS/FW); refresh_many — список устройств в потоке.
  • Группировка нескольких запросов одного ответа в один to_thread: backups.search, backups_page, device_create.
  • API (refresh_device, put_channel, refresh_all, list_backups, batch, batch_channel, запуск задач) и UI (refresh, batch, device_action, device_create, backups_page) — без синхронной БД в event loop.
  • Тест-линтер test_no_sync_db_calls_in_async_functions: AST-обход app/ — в async def нет прямых вызовов функций с session_scope (напрямую или через одну ступень); ссылки в asyncio.to_thread(fn, …) и вложенные def не считаются; сообщение называет файл, функцию и вызов.

Проверено

  • pytest: 29 из 29.
  • Мутация: прямой get_device в refresh_device → линтер падает с точным местом; файл восстановлен.
  • Стенд (8001): бэкап и групповая смена канала для временного устройства → 202, задачи failed (ConnectTimeout, ожидаемо), актор всех событий задач — api (контекст в потоке сохраняется); во время 4-секундного refresh параллельные GET /devices — 0,011 с, GET /backups — 0,125 с.
  • Боевые данные: группы 3/3, устройства 14/14; добавлены только данные проверки (2 задачи, запись неудачного бэкапа, события); временное устройство удалено.

Оговорки

  • Линтер видит одну ступень транзитивности: функция, обращающаяся к БД через две и более промежуточных, не будет обнаружена.
  • Ручная проверка UI пользователем на момент коммита не подтверждена.