AURORA-1845: кэш user/формы на время WS-соединения #238

Open
aep wants to merge 2 commits from feat/237-aurora-1845-ws-connection-cache into test
Owner

Closes #237

Jira: AURORA-1845

Что сделано

  • В FormEventProcess.process пользователь (user_service.get) и проверка доступа к форме (bf_service.get) кэшируются на время WebSocket-соединения листа формы (ConnectionCache, живёт в process_websocket, т.к. процессор и сессия БД создаются на каждое сообщение).
  • Кэшируются только положительные результаты (найденный пользователь, форма доступна); TTL 30 с.
  • ProjectEventProcess, ConnectionManager.disconnect/блокировки (AURORA-1923), get_db_session / SET LOCAL app.user_id не тронуты.
  • Пакетирование правок не делается (вынесено в отдельную задачу).

Тесты

  • unit tests/unit/test_websocket_connection_cache.py: за N сообщений user_service.get/bf_service.get вызваны по 1 разу; без кэша - N; истечение TTL; отрицательные результаты не кэшируются.
  • интеграционный tests/integration/test_websocket_connection_cache_integration.py через websocket_connect (3 цикла edit_start/updated/edit_end, счётчики = 1; значение ячейки откатывается в finally).
  • Полный прогон (PG16): 206 passed, 4 skipped, 3 failed - те же 3 исходных падения.

Проверить руками

  • Открыть лист формы, отредактировать несколько ячеек подряд - правки применяются, аудит показывает правильного пользователя.
  • Удалить/добавить строку - работает.
  • Пользователь без доступа к форме по-прежнему получает отказ.

Замер до/после

Эффект мал, мерить вместе со сценарием coauthor из AURORA-1850.

Rulings I made

  • R-1: кэш с TTL 30 с, а не бессрочный на соединение. Раньше смена роли/орг-юнитов или удаление формы подхватывались со следующего сообщения; бессрочный кэш сделал бы это невозможным до переподключения. Цена ошибки: при слишком большом TTL Python-ветки (admin vs не-admin, org_units в sheet_service) устаревают дольше; при малом - выигрыш меньше.
  • R-2: из формы кэшируется только факт доступа, а не объект (возвращаемое значение bf_service.get в обработчиках не используется). Цена ошибки: нет - объект и не нужен.
  • R-3: отрицательные результаты (пользователь не найден, форма недоступна) не кэшируются - поведение для таких случаев не меняется.
  • R-4: права на запись по-прежнему определяет can_edit в SQL-обёртке upd_form_cells на каждое сообщение; кэш на него не влияет. Деактивация пользователя при живом соединении и раньше не проверялась в process() (только при логине по токену) - не менял.
  • R-5: кэш передаётся только в FormEventProcess (ProjectEventProcess вне задачи).

🤖 Generated with Claude Code

Closes #237 Jira: AURORA-1845 ## Что сделано - В `FormEventProcess.process` пользователь (`user_service.get`) и проверка доступа к форме (`bf_service.get`) кэшируются на время WebSocket-соединения листа формы (`ConnectionCache`, живёт в `process_websocket`, т.к. процессор и сессия БД создаются на каждое сообщение). - Кэшируются только положительные результаты (найденный пользователь, форма доступна); TTL 30 с. - `ProjectEventProcess`, `ConnectionManager.disconnect`/блокировки (AURORA-1923), `get_db_session` / `SET LOCAL app.user_id` не тронуты. - Пакетирование правок не делается (вынесено в отдельную задачу). ## Тесты - unit `tests/unit/test_websocket_connection_cache.py`: за N сообщений `user_service.get`/`bf_service.get` вызваны по 1 разу; без кэша - N; истечение TTL; отрицательные результаты не кэшируются. - интеграционный `tests/integration/test_websocket_connection_cache_integration.py` через `websocket_connect` (3 цикла edit_start/updated/edit_end, счётчики = 1; значение ячейки откатывается в finally). - Полный прогон (PG16): 206 passed, 4 skipped, 3 failed - те же 3 исходных падения. ## Проверить руками - [ ] Открыть лист формы, отредактировать несколько ячеек подряд - правки применяются, аудит показывает правильного пользователя. - [ ] Удалить/добавить строку - работает. - [ ] Пользователь без доступа к форме по-прежнему получает отказ. ## Замер до/после Эффект мал, мерить вместе со сценарием coauthor из AURORA-1850. ## Rulings I made - R-1: кэш с TTL 30 с, а не бессрочный на соединение. Раньше смена роли/орг-юнитов или удаление формы подхватывались со следующего сообщения; бессрочный кэш сделал бы это невозможным до переподключения. Цена ошибки: при слишком большом TTL Python-ветки (admin vs не-admin, org_units в sheet_service) устаревают дольше; при малом - выигрыш меньше. - R-2: из формы кэшируется только факт доступа, а не объект (возвращаемое значение bf_service.get в обработчиках не используется). Цена ошибки: нет - объект и не нужен. - R-3: отрицательные результаты (пользователь не найден, форма недоступна) не кэшируются - поведение для таких случаев не меняется. - R-4: права на запись по-прежнему определяет `can_edit` в SQL-обёртке `upd_form_cells` на каждое сообщение; кэш на него не влияет. Деактивация пользователя при живом соединении и раньше не проверялась в process() (только при логине по токену) - не менял. - R-5: кэш передаётся только в `FormEventProcess` (ProjectEventProcess вне задачи). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 2 commits 2026-10-28 19:18:09 +03:00
AURORA-1845. process() больше не читает user_service.get / bf_service.get на
каждое сообщение: результат кэшируется в ConnectionCache (TTL 30 с, только
положительные результаты).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

Ночной замер на стенде perf/ (29.10, масштаб 1, D0, CPU 1x, arm-ka-* остановлены)

PR рекомендует мерить вместе с coauthor из AURORA-1850. 1845 и 1850 — разные ветки от test/1844, поэтому собрал локальный merge в detached HEAD стенда (a1fa511 = 1850 b5a245e + этот PR 4dae72d, конфликтов нет; не пушился, ветки нет). Фронт в обоих — test.
Команда: PERF_SQLSTATS_TAG=coauthor PERF_TARGETS='FORM_2/AHR/*' PERF_COAUTHOR_RATES=5 PERF_REPEATS=3 scroll-coauthor.spec.ts.

rate 5, FORM_2/AHR 1850 (прогон 1) 1850 (прогон 2) 1850 + 1845
sent / echoed / errors 257.5 / 205 / 52.5 258 / 207 / 51 259.5 / 218.5 / 41
(echoed+errors)/sent 1.00 1.00 1.00
echoed/sent 0.80 0.80 0.84
mean upd_form_cell, мс 29.6 31.1 29.3
main_thread_ms_per_step автора 105.3 105.7 106.1

Вердикт: очереди нет ни до, ни после (на бэке 1850 правки успевают); заметный эффект — меньше ошибочных эх (O-10): 51–52 → 41 за прогон, echoed/sent 0,80 → 0,84. Время SQL правки и нагрузка на автора — без изменений. На бэке test (без 1850) rate 5 не снимается инструментом (O-1: бот теряет итог при ~0,5 с на правку), поэтому замер «1845 от test» не делал. Задержку эха бот не мерит (доработка из design P3 не сделана).

Прогоны: perf/results/n-cof-base, n-cof-base-r2, n-cof-1850x1845 (worktree perf-bench); лог merge — /private/tmp/claude-501/-Users-andrey-epifancev-projects-fomichev-claude/6fa9c75e-eb11-4e5d-98c1-05eb590ab14f/scratchpad/night/logs/merge-1845.log.

🤖 Generated with Claude Code

## Ночной замер на стенде perf/ (29.10, масштаб 1, D0, CPU 1x, arm-ka-* остановлены) PR рекомендует мерить вместе с coauthor из AURORA-1850. 1845 и 1850 — разные ветки от `test`/1844, поэтому собрал **локальный merge** в detached HEAD стенда (`a1fa511` = 1850 b5a245e + этот PR 4dae72d, конфликтов нет; не пушился, ветки нет). Фронт в обоих — `test`. **Команда:** `PERF_SQLSTATS_TAG=coauthor PERF_TARGETS='FORM_2/AHR/*' PERF_COAUTHOR_RATES=5 PERF_REPEATS=3 scroll-coauthor.spec.ts`. | rate 5, FORM_2/AHR | 1850 (прогон 1) | 1850 (прогон 2) | 1850 + 1845 | |---|---|---|---| | sent / echoed / errors | 257.5 / 205 / 52.5 | 258 / 207 / 51 | 259.5 / **218.5** / **41** | | (echoed+errors)/sent | 1.00 | 1.00 | 1.00 | | echoed/sent | 0.80 | 0.80 | **0.84** | | mean upd_form_cell, мс | 29.6 | 31.1 | 29.3 | | main_thread_ms_per_step автора | 105.3 | 105.7 | 106.1 | **Вердикт:** очереди нет ни до, ни после (на бэке 1850 правки успевают); заметный эффект — меньше ошибочных эх (O-10): 51–52 → 41 за прогон, echoed/sent 0,80 → 0,84. Время SQL правки и нагрузка на автора — без изменений. На бэке `test` (без 1850) rate 5 не снимается инструментом (O-1: бот теряет итог при ~0,5 с на правку), поэтому замер «1845 от test» не делал. Задержку эха бот не мерит (доработка из design P3 не сделана). Прогоны: `perf/results/n-cof-base`, `n-cof-base-r2`, `n-cof-1850x1845` (worktree perf-bench); лог merge — `/private/tmp/claude-501/-Users-andrey-epifancev-projects-fomichev-claude/6fa9c75e-eb11-4e5d-98c1-05eb590ab14f/scratchpad/night/logs/merge-1845.log`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This pull request can be merged automatically.
You are not authorized to merge this pull request.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/237-aurora-1845-ws-connection-cache:feat/237-aurora-1845-ws-connection-cache
git checkout feat/237-aurora-1845-ws-connection-cache
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/DFiP_Budget_planing#238
No description provided.