session-07: чанковая загрузка, worker'ы, одно DB-соединение
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Сессия #7 — чанковая загрузка, worker'ы, одно соединение
|
||||
|
||||
_Дата: 2026-06-17_
|
||||
_Версия: v1.15 → v1.18_
|
||||
|
||||
---
|
||||
|
||||
## Проблема
|
||||
|
||||
Загрузка PDF 153 KB падала с «✗ Сеть»:
|
||||
- v1.14: прямая загрузка (один POST) → Ingress режет `client_max_body_size`
|
||||
- v1.15-16: чанки 50KB в памяти `_chunk_store = {}` → worker'ы разные, чанки теряются
|
||||
- v1.17: чанки в PostgreSQL (таблица `chunks`) → всё равно «Сеть»
|
||||
- v1.18: ОДНО DB-соединение на сборку → ?
|
||||
|
||||
## Хронология
|
||||
|
||||
### v1.14: прямая загрузка
|
||||
`POST /` с файлом 153 KB → Ingress (nginx) обрывает → `XHR onerror` → «Сеть»
|
||||
|
||||
### v1.15: чанки 50KB в памяти
|
||||
`POST /chunk` × 3. `_chunk_store = {}` в памяти модуля.
|
||||
**Ошибка:** dict живёт в одном worker'е. Gunicorn с >1 worker → чанки на разных процессах → второй не видит первый → обрыв.
|
||||
|
||||
### v1.16: try/except + проверка doc_id
|
||||
Добавлена обработка ошибок при сборке. **Откачено** (не решило проблему worker'ов).
|
||||
|
||||
### v1.17: чанки в БД
|
||||
Таблица `chunks(upload_id, chunk_index, chunk_data, ...)`. `ON CONFLICT DO NOTHING`.
|
||||
**Всё равно «Сеть»** — worker'ы больше не проблема, но осталась другая.
|
||||
|
||||
### v1.18: одно DB-соединение (текущая)
|
||||
**Диагноз:** `_chunk_upload` при сборке делал до 7 отдельных `db.execute`/`db.query` —
|
||||
каждое = новый `psycopg2.connect`. На managed-платформе это медленно → таймаут Ingress → обрыв.
|
||||
|
||||
**Исправление:**
|
||||
- `_save_file_to_db(filename, file_bytes, mime, contract_id, conn=None)` — принимает соединение
|
||||
- `_chunk_upload` открывает ОДНО соединение на всю сборку:
|
||||
- SELECT chunks
|
||||
- INSERT contracts (если нужно)
|
||||
- INSERT documents
|
||||
- SELECT id документа
|
||||
- INSERT supplements
|
||||
- DELETE chunks
|
||||
- Все 6 запросов в одной транзакции, одно подключение.
|
||||
|
||||
---
|
||||
|
||||
## Архитектура чанков (текущая)
|
||||
|
||||
```
|
||||
Клиент: file.slice(0,50KB) → XHR POST /chunk
|
||||
file.slice(50KB,100KB) → XHR POST /chunk
|
||||
file.slice(100KB,150KB) → XHR POST /chunk
|
||||
|
||||
Сервер /chunk:
|
||||
1. INSERT INTO chunks (...) ON CONFLICT DO NOTHING ← 1 conn
|
||||
2. SELECT COUNT(*) FROM chunks ← 1 conn
|
||||
3. Если received == total_chunks:
|
||||
ОДНО соединение:
|
||||
SELECT chunk_data ORDER BY chunk_index
|
||||
SELECT metadata
|
||||
INSERT INTO contracts (если нет cid)
|
||||
COMMIT
|
||||
→ _save_file_to_db(conn=...)
|
||||
INSERT INTO documents
|
||||
SELECT id
|
||||
INSERT INTO supplements
|
||||
COMMIT
|
||||
DELETE FROM chunks
|
||||
ОТВЕТ {"contract_id": "..."}
|
||||
```
|
||||
|
||||
## Выученные уроки
|
||||
|
||||
1. **`_chunk_store` в памяти не работает с несколькими worker'ами** — нужна общая БД.
|
||||
2. **Много отдельных `db.execute` = много `psycopg2.connect`** — на managed-платформе медленно.
|
||||
3. **Всегда одно соединение для зависимых операций** — сборка + сохранение должны быть атомарны.
|
||||
4. **Анализ агентом помог** — указал на `_save_file_to_db` как узкое место.
|
||||
Reference in New Issue
Block a user