Перекачать файлики...
Перекачать файлики... (пятничная задачка)
Дано:
две системы (клиент и сервер), об которых известно, что одна из них может работать с другой по HTTP(S).
Клиент может запросить у Сервера некоторый набор документов (пакет).
Состав пакета на момент запроса неизвестен ни Клиенту, ни Серверу, определяется Сервером по факту окончания подготовки пакета.
Сервер может:
- либо подготовить запрашиваемый пакет
- либо получить ошибку в процессе подготовки пакета.
Отдавать данные Клиенту Сервер будет по-документно.
Требуется:
получить полный пакет на первой системе.
Ограничения:
HTTP(S) only.
Количество документов в пакете, наименования документов, время подготовки каждого документа и всего пакета - неизвестны. Вторая система "знает" когда закончена подготовка пакета.
Начинать передачу требуется по готовности каждого документа, но готовность всего пакета для Клиента определяется окончанием передачи последнего документа.
Пожелания:
Не хочется иметь поллинг.
Хочется многопоточную загрузку.
Из вариантов.
На второй системе будет реализовываться веб-сервис. Можно сделать ФТП, но это уже не HTTP(S).
Непонятное:
Как, без поллинга, сообщить Клиенту, что готов очередной документ.
Как, без поллинга, сообщить Клиенту, что завершен пакет.
Т.е. нужно реализовать Подписку? Не хочется...
Подумалось, что может работать так:
- Клиент запрашивает Пакет и получает в ответ сообщение об начале подготовки Пакета.
- Сервер, получив запрос на Пакет, создает пустой список файлов с отметкой об начале и на базе этого списка отсылает сообщение об начале подготовки Пакета. Сами файлы в этот момент не создаются, но запускается процедура их создания.
- Клиент запрашивает "Следующий Файл", не зная есть ли файл на сервер (да, похоже на поллинг) и получает один из 4-х ответов (и => реакции):
- - Файл готов, имя файла => запрос к Серверу на передачу файла
- - Файлов больше нет => заканчиваем докачку длинных/медленных файлов и завершаем процесс получения Пакета.
- - Не готово, ждите х секунд => просто тупо ждем указанный период, потом повторяем запрос "Следующий Файл"
-
- Произошла ошибка => терминируем закачку, выкидываем в мусорник все полученное до этого
На Сервере.
По получении запроса Пакета создается пустой "Список Файлов" (не реальные файлы, а лишь список) с записью "Генерация Начата 01/03/2019 16:20" и запускается процесс генерации.
В начале генерации файла создается запись об Файле с маркером - "Генерация Файла Начата", по окончании маркер меняется на "Генерация Файла Закончена". При ошибке маркер меняем на "Ошибка Генерации".
Когда последний из необходимых файлов поступил в генерацию в "Список Файлов" помещается запись "Больше файлов не будет".
По окончанию генерации последнего файла в "Список Файлов" пишем "Генерация завершена".
При получении запроса "Следующий Файл" выполняется:
- "Список Файлов" проверяется на маркер "Ошибка Генерации". Если такой есть - формируется ответ "Произошла Ошибка";
- Берется первая запись из "Списка Файлов" с маркером "Генерация Файла Закончена" и маркер заменяется на "Начата Передача Клиенту". По окончании передачи маркер меняется на "Передача Клиенту завершена".
- При отсутствии маркеров "Генерация Файла Закончена" и записи "Генерация завершена" - формируется ответ "Не готово, ждите х секунд"
- При наличии записи "Генерация завершена" и отсутствии маркеров "Генерация Файла Закончена" Сервер отвечает "Файлов больше нет".
Потенциальная проблемы:
- не отслеживаются ошибки передачи файлоv, но можно добавить МД5 в "Файл Готов" и обязать Клиента сообщать "Файл Получен, имя файла"
- не отслеживаются ошибки некорректной смены маркеров. Можно добавить запрос "Текущий Статус" с ответом "Все Хорошо" и "Жопа, однако..."
Следующая мысль постучалась в пустую голову... наверное пришла пятница?..
Пока обдумывал ситуацию - расхотелось писать генерируемое в файлики.
Захотелось отдавать динамически, сбуферизацией, в сетку, отслеживая сколько скинуто в буфер и иметь управляемый объем буфера.
Ах, да - отдавать надо из Т4 с минимальным вмешательством - т.е. Т4 - остается как есть, меняется - базовый класс. Ну да его все одно менять...