ADR 0007: восстановление сетевых передач в SDK
Статус: принято, 2026-09-22.
Проблема
Сервер сохраняет multipart-части и неизменяемые blobs, но потеря TCP-соединения или ответа после commit останавливала клиент. Наличие Range само по себе не гарантирует корректную докачку: proxy может вернуть полный файл, неверный диапазон или повреждённые байты.
Решение
Portable SDK явно повторяет только создание с прежним Idempotency-Key и шаги resume/downloadVerified. CAS metadata/assets/restore и остальные вызовы не получают неявных повторов. Transport errors отделены от ошибок схемы и целостности. Один бюджет охватывает все части/диапазоны операции; на запрос действует дополнительный предел попыток. Backoff с jitter учитывает Retry-After. Если сервер требует ждать дольше локального лимита, возвращаем ошибку без раннего повтора.
Повтор multipart PUT сохраняет upload ID, индекс, размер и SHA-256. Повтор complete использует серверную идемпотентность опубликованного состояния. Для пустого файла перед повтором PUT запрашивается статус: уже опубликованный объект не загружается снова. Незавершённая отменённым клиентом сессия остаётся возобновляемой до серверного TTL, если пользователь не отменил её через DELETE.
downloadVerified получает доступный immutable artifact и читает последовательные диапазоны не более 8 MiB. Каждый запрос содержит Range и If-Range. Ответ обязан иметь 206, точный Content-Range/Content-Length и сильный SHA-256 ETag; Content-Encoding кроме identity запрещён. Разрыв/недополученный блок повторяется целиком до передачи потребителю. Backpressure допускает только один запрашиваемый блок. Проверка полного SHA-256 предшествует выдаче последнего блока и успешному закрытию потока. Библиотека @noble/hashes 2.4.0 (MIT), уже использовавшаяся в web hash worker, теперь явно объявлена зависимостью SDK; license включается в web THIRD-PARTY.txt.
Для восстановления после перезапуска клиент может передать immutable Blob prefix, содержащий сохранённое начало файла. SDK заново хеширует его ограниченными кусками и выдаёт только оставшийся суффикс. Клиент отвечает за локальное временное хранение, устойчивость подтверждённых записей, связь prefix с целевым файлом и окончательный commit. Успехом является закрытие потока, а не достижение размера файла. При неверном prefix финальная проверка не даёт commit. SDK не обещает раннюю проверку отдельных download-блоков: сервер пока публикует только хеш целого объекта.
Границы
Проволочный API и схема БД не изменяются. Низкоуровневый download по-прежнему возвращает Response без автоматического восстановления/хеширования. Web использует новый поток и pipeTo: запись закрывается только после проверки, ошибка вызывает abort destination. Сохранение download checkpoint между перезапусками браузера пока не реализовано.
Буфер до 8 MiB на активный диапазон плюс транспортные буферы и состояние hash. При разрыве повторяется максимум текущий блок; неизменяемый префикс не загружается из сети повторно. Это не распределённый scheduler и не failover. Двухсерверные проверки остаются отложенными.
HTTP-основание: RFC 9110, Range, Retry-After.