Прежде всего, вау, Rails 1.2.7. У меня на работе такое же старое приложение, которое я постепенно обновляю до Rails 3. Сумасшедший, как быстро меняется этот материал.
Определенно веселая проблема. Есть много направлений, по которым вы могли бы пойти по этому пути, и я не уверен, что лучше, так как я не уверен, что понимаю ваш процесс. Поэтому я предложу пару. Насколько я понимаю, 1) Загрузить файл, 2) Начать конвертацию, 3) Отчет о статусе конвертации с помощью опроса ajax.
Во-первых, как вы обнаружили, запуск утилиты конвертации в действии контроллера Rails определенно не подходит. 1) Ваш веб-сервер или браузер, вероятно, убьют запрос, и 2) большинство развертываний Rails допускают только один запрос за одно приложение, то есть, если вы хотите, чтобы 5 одновременных пользователей загружали, вам нужно 5 запущенных копий вашего приложения. Очевидно, что это не будет масштабироваться.
Ваше действие по загрузке должно быть максимально быстрым. Он должен 1) загрузить файл и 2) либо запланировать, либо запустить «задание преобразования», которое обрабатывает какой-то другой процесс. Тогда ваш опросный лист просто сообщит о состоянии этой работы. Конечно, вопрос в том, каким должен быть этот другой процесс.
Идея 1
http://geekblog.vodpod.com/2007/08/17/background-processing-in-rails/, вероятно, хорошее место для начала, хотя я не могу поручиться за такой подход.
Идея 2
Я сделал что-то похожее на это, поэтому я могу дать более подробную информацию. И это, вероятно, масштабируется лучше. Создайте легкое приложение-компаньон, используя Sinatra или Async Sinatra. Ваше Rails-приложение запишет задание для загруженного файла в вашей базе данных, но затем его часть будет выполнена. Ваше приложение Sinatra, использующее EventMachine, будет опрашивать БД каждые несколько секунд и запускать новые задания. Возможно, вы захотите ограничить количество одновременных заданий n, чтобы не создавать DOS для своего собственного ящика :) Затем ваши пользователи могут опрашивать ваше приложение Sinatra, чтобы получить статус их конверсии.
Идея 3
Аналогично 2, но вместо сопутствующего веб-приложения это просто небольшая Ruby-программа, использующая EventMachine. Вы просто запустите эту программу на своем сервере и дадите ей работать вечно. Каждое задание будет записывать свой статус обратно в базу данных, которую ваши пользователи могут опрашивать через ваше приложение Rails. Я думаю, что это мой любимый. Каркасные:
#!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
# Returns new jobs from the database
def new_jobs
[]
end
# Convert the file
def convert(job)
`convert #{job.path}`
job
end
# Callback when conversion is complete
def callback(job)
puts "Finished #{job.path}!"
end
EventMachine::run do
# Run every 5 seconds
EventMachine::add_periodic_timer(5) do
new_jobs.each { |job| EventMachine::defer convert(job), callback(job) }
end
end
Эти предположения, по общему признанию, с высоты 10 000 футов, но я надеюсь, что есть кое-что, что поможет вам начать.