fix(hub): Python от uv вместо miniconda — SQLite 3.51.1 вешал хаб взаимной блокировкой (O-14, R-11, #29)
Стеки зависшего тестового хаба: потоки запросов ждут мьютексы unix-VFS SQLite в sqlite3.connect (findReusableFd) и close (sqlite3WalClose -> unixLock). Ошибка SQLite 3.51.0–3.51.1, исправлена в 3.51.2. .python-version = 3.13 и tool.uv.python-preference = only-managed: uv берёт свой CPython 3.13.12 (SQLite 3.50.4) и сам пересоздаёт .venv. Тест не даёт вернуться на SQLite 3.51.0–3.51.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
009fc30dd1
commit
447d878e0e
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
||||
3.13
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
## Стек и ограничения
|
||||
- Веб-приложение — `web/` (React 19 + TypeScript + Vite, TanStack Query, Vitest, Playwright; Node 24, npm); сборка в `src/jira_hub/web/app/` не в git.
|
||||
- Python 3.13, uv, hatchling, pytest; HTTP на stdlib (`http.server`), БД — SQLite (stdlib), MCP — пакет `mcp` (закреплён `<2`, рулинг R-10).
|
||||
- Python 3.13 от uv (`.python-version`, `tool.uv.python-preference = "only-managed"`: системный Python miniconda несёт SQLite 3.51.1 с взаимной блокировкой, O-14 #29), uv, hatchling, pytest; HTTP на stdlib (`http.server`), БД — SQLite (stdlib), MCP — пакет `mcp` (закреплён `<2`, рулинг R-10).
|
||||
- Хаб не знает пароль Jira и не ходит в Jira: учётные данные и сеть до Jira только у агента.
|
||||
- Зеркало задач пишет только `mirror.apply_state` по загрузке состояния от агента (`POST /agent/state`); правки идут командами через очередь.
|
||||
- Хаб не создаёт команды сам: повтор после failed — новая команда по запросу человека/интерфейса. Команду, выданную агенту и оставшуюся без отчёта, хаб довыдаёт при следующем claim (до 3 выдач, затем failed).
|
||||
|
||||
@ -11,6 +11,10 @@ HTTP API в локальной сети и MCP-сервер для Claude. Ха
|
||||
uv sync
|
||||
```
|
||||
|
||||
Python для хаба uv ставит свой (3.13, `.python-version`; системный и conda-Python не берутся — `tool.uv` в
|
||||
`pyproject.toml`): в SQLite 3.51.0–3.51.1 есть взаимная блокировка, от которой хаб зависал под параллельными запросами.
|
||||
Первый `uv sync` или `uv run` после смены сам пересоздаёт `.venv`.
|
||||
|
||||
Данные лежат в `~/.local/share/jira-hub/` (каталог переопределяется переменной `JIRA_HUB_HOME`):
|
||||
`hub.sqlite` и `backups/`. Пакет `mcp` закреплён версией `<2` (рулинг R-10): MCP SDK 2.x ломает API.
|
||||
|
||||
|
||||
@ -158,3 +158,15 @@ jira-hub#29 (46 пунктов, маркеры сохраняются из PR #2
|
||||
клик по видимой карточке без ожидания кадров. Обоснование: воспроизвести потерю прокрутки у пользователя, кликающего по
|
||||
видимой карточке, не удалось ни в e2e, ни вручную. Цена ошибки: если дефект есть у реальных пользователей (например,
|
||||
в браузере с иной раскладкой событий scroll), прокрутка после возврата будет 0; чинится сохранением в cleanup `useLayoutEffect` (до снятия DOM).
|
||||
- **R-11, 15.10.2026.** O-14 (зависание тестового хаба в e2e) — не дефект приложения, а взаимная блокировка в unix-VFS
|
||||
SQLite 3.51.1 (исправлена в 3.51.2): стеки снятого зависшего хаба — все потоки запросов в `sqlite3.connect`
|
||||
(`findReusableFd`) и один в `close` (`sqlite3WalClose` → `unixLock`), ждут мьютексы друг друга. SQLite 3.51.1 — у Python
|
||||
miniconda, на котором стоял `.venv` (и у живого хаба). Хаб переведён на Python 3.13 от uv (python-build-standalone,
|
||||
SQLite 3.50.4): `.python-version` = 3.13, `[tool.uv] python-preference = "only-managed"`; тест
|
||||
`test_sqlite_without_unix_vfs_deadlock` не даёт вернуться на 3.51.0–3.51.1. Проверка: на старом окружении хаб завис на
|
||||
3-м и 5-м прогонах e2e, на новом — 20 прогонов подряд без зависаний (и 20 — на Python 3.14 с SQLite 3.53.4). Python 3.14
|
||||
не взят: в нём `Path.is_dir()` при отказе доступа возвращает False вместо исключения, и реле пишет «папки нет» вместо
|
||||
«нет доступа» (падает `test_permission_denied_warns_once_then_works`). Обоснование: правка в границах #29, потому что
|
||||
без неё не выполняется условие I-1 (10 прогонов e2e подряд); код хаба не меняется. Цена ошибки: живой хаб при первом
|
||||
запуске после merge сам пересоздаёт `.venv` на Python от uv (нужен интернет для загрузки, ~1 мин); если что-то пойдёт
|
||||
не так — убрать `[tool.uv]` и `.python-version`, `uv sync`, перезапуск.
|
||||
|
||||
@ -20,3 +20,8 @@ packages = ["src/jira_hub"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
|
||||
[tool.uv]
|
||||
# Python от uv (python-build-standalone): SQLite в нём своя. В SQLite 3.51.0–3.51.1 взаимная блокировка в unix-VFS
|
||||
# вешает хаб под параллельными запросами (O-14, #29); у miniconda — 3.51.1
|
||||
python-preference = "only-managed"
|
||||
|
||||
@ -194,3 +194,9 @@ def test_migrated_claimed_redelivered_end_to_end(tmp_path):
|
||||
assert cmd["id"] == 1
|
||||
assert queue.get_command(conn, 1)["deliveries"] == 2
|
||||
conn.close()
|
||||
|
||||
|
||||
def test_sqlite_without_unix_vfs_deadlock():
|
||||
# O-14 (#29): в SQLite 3.51.0–3.51.1 взаимная блокировка в unix-VFS (исправлена в 3.51.2) вешала хаб под
|
||||
# параллельными запросами — потоки ждали друг друга в sqlite3.connect/close. Python хаба — от uv (pyproject, tool.uv)
|
||||
assert sqlite3.sqlite_version_info[:2] != (3, 51) or sqlite3.sqlite_version_info >= (3, 51, 2), sqlite3.sqlite_version
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user