Я тут внезапно понял очевидную вещь: как надо отдавать несколько файлов с сервера одним архивом. Собственно, после http-хедеров нужно перенаправить вывод tar/7z/zip в сокет, и всё — никаких временных файлов, создания архивов на все случаи жизни, стораджа для архивов, ожидания, пока мои два гигабайта заархивируются на сервере и прочего.
Правда, 206 прямо с ходу работать не будет, но это мелочи жизни (которые, кстати, можно и исправить, но ценой некоторого процессорного времени).
Понятно, что решение очевидное, но я не встречался с ним ни разу.
Правда, 206 прямо с ходу работать не будет, но это мелочи жизни (которые, кстати, можно и исправить, но ценой некоторого процессорного времени).
Понятно, что решение очевидное, но я не встречался с ним ни разу.
no subject
Date: 2009-10-22 09:14 am (UTC)Я, помнится, когда ваял кастомный TCP клиент-сервер для передачи пакетов данных (они были в виде tar), вначале заложился как раз на то, что архив будет сливаться прямо в сокет. Но возникла проблема с заголовками, которые должны быть прочитаны на приемнике раньше, чем данные, а порождены передатчиком могут быть только после генерации им всех данных. Более того, поскольку генерация данных для пересылки -- time-consuming, то любая мелкая ошибка при передаче -- и нужно всю выгрузку рубить и начинать заново (или же контролировать размер каждой выгрузки, что усложняет генерацию). Поэтому было сделано все с кэшированием запаса последних файлов на диске. Потом, кстати, на этой основе вышла неплохая схема redundancy: при условии передачи пакетов по ненадежному одностороннему каналу, защититься от пропусков (которые обнаружить-то на приемнике можно, а вот перезапросить что-то после этого очень сложно) можно если возить с собой каждый раз метапакет из последних N пакетов, ценою емкости носителя (а это для задачи было допустимо). Чувствую здесь велосипед из области TCP/IP, но так и не добрался до литературы ;)
Наверное, в случае генерации пакета "на лету" оптимальной может оказаться схема с tee -- одной рукой кладешь в сокет, а другой -- на диск, и если в сокете сорвалось, то, не перезапуская архиватора, новую попытку передачи начинаешь уже с диска и "догоняешь" растущий конец файла. И так пока не передашь, а потом файл стираешь.
Кстати, недавно узнал -- оказыватеся, для rsync'а губительно, когда в середину большого gzip-архива добавляется один файл -- ему придется всю вторую половину передавать. Поэтому и была добавлена опция gzip --rsyncable, которая периодически "начинает архив заново", благодаря чему число фрагментов архива, затронутых добавлением файла, сильно сокращается. Красиво.
no subject
Date: 2009-10-22 10:25 am (UTC)Именно http, так-то tar czf|nc все делали.
Про tee хорошая идея.
Про gzip --rsyncable не знал, пригодится.