Лучшая практика для Rails App для запуска длинной задачи в фоновом режиме? - PullRequest
32 голосов
/ 03 февраля 2009

У меня есть приложение 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:

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

Редактировать 5:

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

Ответы [ 14 ]

24 голосов
/ 03 февраля 2009

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

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

6 голосов
/ 20 февраля 2009

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

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

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

4 голосов
/ 20 февраля 2009

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

2 голосов
/ 04 февраля 2014

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

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

2 голосов
/ 20 февраля 2009

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

Было бы задание cron, которое запускает вашу пользовательскую задачу Rake как отдельный процесс Ruby, поэтому основное приложение Rails не затрагивается. Задача Rake может использовать ActiveRecord, чтобы найти все модели, которые имеют представленное состояние , изменить состояние на , обрабатывающее , а затем сгенерировать связанные PDF-файлы. Наконец, он должен установить состояние complete . Это позволяет вашим вызовам 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 для регулярного создания довольно тяжелого процесса Ruby, а сроки ваших заданий cron потребуют тщательной настройки, чтобы у каждого было достаточно времени для завершения, прежде чем появится следующий. Однако этот подход прост и должен отвечать вашим потребностям.

1 голос
/ 07 февраля 2014

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

Resque

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

Resque-статус

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

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

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

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

1 голос
/ 25 февраля 2009

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

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

1 голос
/ 19 февраля 2009

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

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

0 голосов
/ 09 марта 2011

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

0 голосов
/ 26 февраля 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...