3.7 KiB
3.7 KiB
Сессия #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": "..."}
Выученные уроки
_chunk_storeв памяти не работает с несколькими worker'ами — нужна общая БД.- Много отдельных
db.execute= многоpsycopg2.connect— на managed-платформе медленно. - Всегда одно соединение для зависимых операций — сборка + сохранение должны быть атомарны.
- Анализ агентом помог — указал на
_save_file_to_dbкак узкое место.