4.4 KiB
Contract: Batch File Upload
Version: 1.0
Purpose
ADR: стратегия загрузки большого числа файлов через multipart-запросы без переработки серверного pipeline и без скрытых лимитов.
ADR
Дата: 2026-03-01 Статус: Accepted
Контекст
Клиент должен загрузить список файлов на сервер для обработки. Загрузка всех файлов одним multipart-запросом упирается в скрытые лимиты: количество parts, размер тела запроса (413), таймауты соединения. Переработка серверного pipeline под стриминговую загрузку — отдельная дорогостоящая задача.
Решение
Клиент делит список файлов на батчи фиксированного размера и отправляет каждый батч отдельным multipart-запросом.
- Размер батча определяется константой
MAX_FILES_PER_BATCH(выбирается проектом). - Батчи считаются по числу файлов, не только по байтам.
- Обработка батчей последовательная по умолчанию. Параллельная обработка допускается только если явно оговорена и задокументирована.
- Каждый батч производит отдельный downloadable артефакт, либо агрегируется на финальном шаге — решение принимается на уровне проекта.
Последствия
Плюсы:
- Избегаем скрытых лимитов на количество multipart parts
- Снижаем риск таймаутов и ошибок 413
- Не требует немедленной переработки серверного parser pipeline
Минусы:
- Больше round-trips (N батчей = N запросов)
- Несколько выходных файлов если артефакты не агрегируются
- Более долгий end-to-end UX для пользователя
Правила реализации
Константа батча
const MaxFilesPerBatch = 1000 // выбирается проектом
Константа объявляется явно — не хардкодится inline.
Именование артефактов
Результаты батчей именуются с суффиксом _partN:
report_part1.csv
report_part2.csv
report_part3.csv
Или агрегируются в единый файл на финальном шаге — тогда суффикс не нужен.
Обработка ошибок
- Ошибку превышения лимита parts (
multipart: too many parts) не маскировать под ошибку размера. - Логировать первичную причину с явным указанием типа лимита.
- Клиент при получении ошибки лимита должен уменьшить батч и повторить, либо сообщить пользователю.
// Правильно
log.Error("batch upload failed: multipart parts limit exceeded", "batch", batchNum, "files", len(batch))
// Неправильно
log.Error("batch upload failed: file too large") // маскирует причину
UI
UI обязан показывать пользователю:
- Общее количество батчей (проходов):
Шаг 2 из 5 - Прогресс текущего батча: прогресс-бар или процент
- Финальный статус каждого батча до начала следующего
Пользователь не должен видеть технический термин "батч" — использовать "шаг" или "проход".
Связанные контракты
go-background-tasks— каждый батч запускается как фоновая задачаimport-export— именование и доставка артефактов