Files
bible/rules/patterns/batch-file-upload/contract.md
2026-03-01 18:22:42 +03:00

4.4 KiB
Raw Blame History

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 — именование и доставка артефактов