2011-01-17 4 views
8

Одной из обязанностей моего приложения Rails является создание и обслуживание подписанных xmls. Любой подписанный xml, после его создания, никогда не изменяется. Поэтому я храню каждый xml в папке public и перенаправляю клиента надлежащим образом, чтобы избежать ненужной обработки с контроллера.Обслуживание динамических zip-файлов через Apache

Теперь я хочу новую функцию: каждый xml связан с датой, и я хотел бы реализовать возможность обслуживать сжатый файл, содержащий каждый xml, дата которого находится в периоде, указанном клиентом. Тем не менее, этот период не может быть ограничен менее чем одним месяцем, чтобы функция была полезной, и это означает, что некоторые файлы zip, которые будут обслуживаться, будут такими же большими, как 50M.

Мое приложение развернуто как пассажирский модуль Apache. Таким образом, совершенно неприемлемо обслуживать файл с send_data, так как клиенту придется ждать, пока весь сжатый файл будет создан до начала фактической загрузки. Хотя у меня есть идея о том, как реализовать эту функцию в Rails, поэтому сжатый файл создается , пока он обслуживается. Я чувствую, что мой сервер будет работать на ресурсах, как только некоторые длинные процессы Ruby/Passenger будут распределены для обслуживания больших zip-файлов.

Я читал о a better solution, чтобы обслуживать статические файлы через Apache, но не динамические.

Итак, в чем проблема? Нужно ли мне что-то вроде пользовательского обработчика Apache? Как сообщить Apache из моего приложения, как обрабатывать запрос, сжимать файлы и передавать результат одновременно?

+0

Индекс формата файла ZIP в конце файла. Кроме того, я быстро просмотрел RFC 2616 (HTTP 1.1) и ответ переменной длины, который, вероятно, работает, хотя обычно должна быть объявлена ​​длина контента. Технически это должно быть возможно, насколько я могу судить. – erloewe

+0

Нет проблемы с HTTP, когда вы заранее не знаете длину, это то, для чего предназначена кодировка передачи. Вы можете писать байты, которые выглядят как zip-файл на любом языке, просто обязательно периодически очищайте свой вывод. – covener

ответ

3

Проверьте мой mod_zip модуль для Nginx:

http://wiki.nginx.org/NgxZip

Вы можете иметь бэкенд скрипт сказать Nginx, какой URL места, чтобы включить в архив, а Nginx будет динамически поток в ZIP-файл клиенту, содержащий эти файлы. Модуль использует однопоточный прокси-код Nginx и очень легкий.

Модуль был впервые выпущен в 2008 году и довольно зрелый на этом этапе. Из вашего описания я думаю, что это подойдет вашим потребностям.

0

Вам просто нужно использовать любой API, который у вас есть, для создания zip-файла и записать его в ответ, периодически промывая выход. Если это обслуживает большие zip-файлы или будет часто запрашиваться, попробуйте запустить его в отдельном процессе с высоким значением nice/ionice/low priority.

В худшем случае вы можете запускать zip-строку в низкоприоритетном процессе и периодически передавать результат.

0

Это сложно сделать, но я сделал драгоценный камень под названием zipline (http://github.com/fringd/zipline), который заставляет меня работать. Я хочу обновить его, чтобы он мог поддерживать простые файловые дескрипторы или пути, прямо сейчас он предполагает, что вы используете несущую ...

также, возможно, вы, вероятно, не сможете передать ответ пассажиру ... Мне пришлось используйте единорог, чтобы обеспечить корректную работу потоковой передачи ... и некоторое промежуточное ПО промежуточного слоя может даже завинтить это (вызов ответа.to_s ломает его)

если кто-нибудь еще это нужно беспокоить меня на GitHub странице

Смежные вопросы