Подтвердить что ты не робот

Лучшая практика для Rails App для выполнения длинной задачи в фоновом режиме?

У меня есть приложение Rails, которое, к сожалению, после запроса контроллеру, должно выполнить хруст, который занимает некоторое время. Каковы наилучшие практики в Rails для обеспечения обратной связи или прогресса в долгосрочной задаче или запросе? Эти методы контроллера обычно продолжаются 60 секунд.

Я не заинтересован в стороне клиента... Я планировал каждый раз запрашивать Ajax-запрос и показывать индикатор прогресса. Я просто не уверен в лучшей практике Rails, я могу создать дополнительный контроллер? Есть ли что-то умное, что я могу сделать? Я хочу, чтобы ответы фокусировались на стороне сервера, используя только Rails.

Заранее благодарим за помощь.

Edit:

Если это имеет значение, http-запрос предназначен для PDF файлов. Затем у меня есть Rails в сочетании с Ruport, создающими эти PDF файлы. Проблема в том, что эти PDF файлы очень большие и содержат много данных. Имеет ли смысл использовать фоновое задание? Предположим, что средний PDF занимает от одной минуты до двух минут, не заставит ли мое приложение Rails не отвечать на любой другой запрос сервера за это время?

Изменить 2:

Хорошо, после дальнейшего расследования кажется, что мое приложение Rails действительно не отвечает на любые другие HTTP-запросы после того, как запрос поступит в большой PDF файл. Итак, я думаю, теперь вопрос становится следующим: Каков наилучший механизм многопоточности/фона? Он должен быть стабильным и поддерживаться. Я очень удивлен, что у Rails нет чего-то подобного.

Изменить 3:

Я прочитал эту страницу: http://wiki.rubyonrails.org/rails/pages/HowToRunBackgroundJobsInRails. Я хотел бы прочитать о различных опытах с этими инструментами.

Изменить 4:

Я использую Passage Phusion "modrails", если это имеет значение.

Изменить 5:

Я использую 64-разрядную версию Windows Vista для своей машины разработки; однако моя производственная машина Ubuntu 8.04 LTS. Должен ли я рассмотреть возможность перехода на Linux для моей машины разработки? Будут ли представленные решения работать на обоих?

4b9b3361

Ответ 1

Плагин Workling позволяет планировать фоновые задачи в очереди (они будут выполнять длительную задачу). Начиная с версии 0.3 вы можете запросить у работника статус, это позволит вам отображать некоторые отличные индикаторы выполнения.

Еще одна интересная функция с Workling заключается в том, что асинхронный бэкэнд можно переключать: вы можете использовать DelayedJobs, Spawn (классическая вилка), Starling...

Ответ 2

У меня очень большой объемный сайт, который генерирует большое количество больших CSV файлов. Для этого иногда требуется несколько минут. Я делаю следующее:

  • У меня есть таблица заданий с подробной информацией о запрошенном файле. Когда пользователь запрашивает файл, запрос отправляется в эту таблицу, и пользователь переходит на страницу "Статус задания", в которой перечислены все их задания.
  • У меня есть задача rake, которая выполняет все выдающиеся задания (метод класса в модели Job).
  • У меня есть отдельная установка рельсов на другой блок, который обрабатывает эти задания. Этот блок просто выполняет задания и недоступен для внешнего мира.
  • В этом отдельном окне задание cron запускает все выдающиеся задания каждые 60 секунд, если только задания не выполняются из последнего вызова.
  • Страница состояния задания пользователя автоматически обновляется, чтобы отобразить состояние задания (которое обновляется в поле заданий при запуске, запуске, завершении задания). После выполнения задания появляется ссылка на файл результатов.

Это может быть слишком тяжело, если вы просто планируете один или два запуска за раз, но если вы хотите масштабировать...:)

Ответ 3

вызов./script/runner в фоновом режиме работал лучше всего для меня. (Я также делал PDF-генерации.) Он кажется самым низким общим знаменателем, а также самым простым в реализации. Вот запись моего опыта.

Ответ 4

Простым решением, которое не требует дополнительных Gems или плагинов, было бы создание пользовательской задачи Rake для обработки генерации PDF. Вы можете смоделировать процесс генерации PDF как конечный автомат с состояниями, такими как отправленные, обработанные и завершающие, которые хранятся в таблице базы данных модели. Первоначальный HTTP-запрос к Rails-приложению просто добавит запись в таблицу с представленным состоянием и возвращает.

Было бы задание cron, которое запускает вашу задачу Rake как отдельный процесс Ruby, поэтому основное приложение Rails не затрагивается. Задача Rake может использовать ActiveRecord для поиска всех моделей, у которых есть предоставленное состояние, изменения состояния для обработки и затем создания связанных PDF файлов. Наконец, он должен установить состояние для завершения. Это позволяет вашим вызовам AJAX в приложении Rails отслеживать состояние процесса генерации PDF.

Если вы ставите свою задачу Rake в your_rails_app/lib/tasks, то она имеет доступ к моделям в вашем приложении Rails. Скелет такого pdf_generator.rake будет выглядеть так:

namespace :pdfgenerator do
  desc 'Generates PDFs etc.'
  task :run => :environment do

    # Code goes here...
  end
end

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

Ответ 5

Это выглядит довольно старая нить. Однако то, что у меня было в моем приложении, для запуска нескольких Таймеров обратного отсчета для разных страниц, должно было использовать Ruby Thread. Таймер должен продолжать работать, даже если страница была закрыта пользователями.

Ruby упрощает запись многопоточных программ с классом Thread. Рубиновые потоки - это легкий и эффективный способ достижения parallelism в вашем коде. Надеюсь, это поможет другим странникам, которые хотят получить опыт: parallelism/параллельные службы в своем приложении. Аналогично, Ajax намного проще вызывать определенное Rails [настраиваемое] действие каждую секунду.

Ответ 6

Это действительно похоже на то, что у вас должен быть фоновый процесс, а не экземпляр приложения (пассажир/дворняжка в зависимости от того, что вы используете) таким образом, что ваше приложение может продолжать делать то, что оно должно делать, обслуживать запросы, в то время как фоновая задача какого-то рода, Workling хорошо, обрабатывает число хруст. Я знаю, что это не касается вопроса о прогрессе, но, если это абсолютно не важно, я думаю, что это небольшая цена, которую нужно заплатить.

Пользователь может щелкнуть требуемое действие, чтобы это действие передало запрос в очередь Workling и отправило ему какое-то уведомление, когда оно будет завершено, возможно, электронное письмо или что-то еще. Я не уверен в практичности этого, просто задумываясь вслух, но я хочу сказать, что это действительно похоже на то, что это должно быть какой-то фоновой задачей.

Ответ 7

Я использую 64-разрядную версию Windows Vista для моего разработка машины; однако, мой производственная машина Ubuntu 8.04 LTS. Должен ли я переходить на Linux? для моей машины разработки? Будет ли представленные решения работают на обоих языках:

Рассматривали ли вы запуск Linux в виртуальной машине поверх Vista?

Ответ 8

Я рекомендую использовать Resque с ним resque-status для ваших тяжелых фоновых процессов.

Resque

Resque - это библиотека Ruby с поддержкой Redis для создания фоновых заданий, помещая их в несколько очередей и обрабатывая их позже.

Resque-статус

resque-status - это расширение для системы очереди resque, которая обеспечивает простые отслеживаемые задания.

Как только вы запустите задание на рабочем столе Resque, используя расширение resque-status, вы сможете получить информацию о ваших текущих достижениях и способности убить конкретный процесс очень легко. Примеры:

status.pct_complete #=> 0
status.status #=> 'queued'
status.queued? #=> true
status.working? #=> false
status.time #=> Time object        
status.message #=> "Created at ..."

Также resque и resque-status имеют классный веб-интерфейс для взаимодействия с вашими заданиями, которые так классны.

Ответ 10

Я использую фоновое задание (http://codeforpeople.rubyforge.org/svn/bj/trunk/README) для планирования задач. Я создаю небольшой сайт администрирования, который позволяет администраторам сайтов запускать всевозможные вещи, которые вы и я запускаем из командной строки из приятного веб-интерфейса.

Ответ 11

Я знаю, что вы сказали, что не беспокоитесь о стороне клиента, но я подумал, что вы можете найти это интересным: Growl4Rails - стиль роста уведомления, которые были разработаны для значительной части того, что вы делаете, судя по используемому ими примеру.

Ответ 12

Я использовал spawn раньше и определенно рекомендовал бы его.

Невероятно прост в настройке (чего многие другие решения нет) и работает хорошо.

Ответ 13

Отъезд BackgrounDRb, он предназначен именно для сценария, который вы описываете.

Я думаю, что это было какое-то время и довольно зрело. Вы можете контролировать статус рабочих.

Это очень хорошая идея для разработки на той же платформе разработки, что и ваша производственная среда, особенно при работе с Rails. Предложение запустить Linux в виртуальной машине является хорошим. Ознакомьтесь с Sun xVM для программного обеспечения для виртуализации с открытым исходным кодом.

Ответ 14

Я лично использую плагин active_messaging с сервером activemq (протокол stomp или rest). Это было чрезвычайно стабильно для нас, обрабатывая миллионы сообщений в месяц.