Асинхронная система задач поверх Rails? - PullRequest
1 голос
/ 06 апреля 2011

В настоящее время я управляю устаревшим приложением rails, работающим на rails 1.2.7.Одна из функциональных возможностей позволяет людям загружать звуки и конвертировать их с помощью инструмента командной строки с помощью обратных галочек.В настоящее время я использую опрос AJAX для управления преобразованием через действие контроллера, но у меня возникают проблемы с тайм-аутами, что означает, что конечные элементы действия контроллера просто не выполняются.

Это системачто требует низких накладных расходов, что я могу использовать для управления этим фоновым преобразованием, а затем реагировать в четной системе на проблемы, созданные фоновым преобразованием?Я смотрел на eventmachine, но я все еще не на 100% с этим, есть ли какие-нибудь другие системы, основанные на асинхронных задачах, которые я мог бы использовать?

1 Ответ

1 голос
/ 06 апреля 2011

Прежде всего, вау, 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 футов, но я надеюсь, что есть кое-что, что поможет вам начать.

...