2009-05-22 3 views
28

Когда новый ресурс создан, и он должен сделать некоторые длительной обработки до ресурс готов, как я посылаю, что обработка далеко в фоновом режиме где не будет держать текущий запрос или другой трафик на мое веб-приложение?Ruby on Rails: Как запустить вещи в фоновом режиме?

в моей модели:

class User < ActiveRecord::Base 
after_save :background_check 

protected 
def background_check 
    # check through a list of 10000000000001 mil different 
    # databases that takes approx one hour :) 
    if(check_for_record_in_www(self.username)) 
    # code that is run after the 1 hour process is finished. 
    user.update_attribute(:has_record) 
    end 
end 
end 

ответ

39

Вы должны обязательно проверить следующие Railscasts:

Они объясняют, как выполнять фоновые процессы в Rails в всевозможном (с или без aq ueue ...)

+2

В эти дни, наиболее используемые/лучше поддерживаемые опции [sidekiq] (https://github.com/mperham/sidekiq), [спасательное ] (https://github.com/defunkt/resque) и [delayed_job] (https://github.com/collectiveidea/delayed_job). IMHO, Sidekiq является лучшим для высокопроизводительных очередей, а delayed_job является лучшим для очень низкой пропускной способности. –

+0

Другим вариантом является [IronWorker] (http://www.iron.io), если вы хотите, чтобы обработка фона «как услуга» и никогда не беспокоиться о идее серверов или очередей. IronMQ/IronWorker также предлагает автоматические повторы, журналы задач, webhooks и т. Д. Он прекрасно сочетается с Rails. Вот несколько видеороликов: https://www.youtube.com/user/ironiodevelopers – Chad

7

Запустить отдельный процесс, который, вероятно, легче всего сделать с system, предваряя ее «поЬир» и присоединени «&» в конце команды вы передаете его. (Убедитесь, что команда только один аргумент строки, а не список аргументов.)

Есть несколько причин, которые вы хотите сделать это таким образом, а не, скажем, пытается использовать темы:

  1. Нити Ruby могут быть немного сложными, когда дело доходит до ввода-вывода; вы должны позаботиться о том, чтобы некоторые вещи, которые вы делаете, не приводили к блокированию всего процесса.

  2. Если вы запускаете программу с другим именем, ее легко идентифицировать в «ps», поэтому вы случайно не думаете, что это конец FastCGI, который был одинок или что-то еще, и убить его.

Действительно, процесс вы начинаете должны быть «deamonized,» видеть Daemonize класс для помощи.

2

Вы в идеале хотите использовать существующий фоновый сервер заданий, а не писать свои собственные. они обычно позволят вам отправить задание и дать ему уникальный ключ; вы можете затем использовать ключ для периодического запроса сервера заданий для статуса вашей работы без блокировки вашего веб-приложения. here is a nice roundup различных вариантов.

0

насчет:

def background_check 
    exec("script/runner check_for_record_in_www.rb #{self.username}") if fork == nil 
end 

Программа «check_for_record_in_www.rb», то будет работать в другом процессе и будет иметь доступ к ActiveRecord, будучи в состоянии получить доступ к базе данных.

1

Мне нравится использовать backgroundrb, его приятно, что вы можете общаться с ним во время длительных процессов. Таким образом, у вас могут быть обновления статуса в вашем приложении rails

1

Я думаю, что spawn - отличный способ разблокировать ваш процесс, сделать некоторую обработку в фоновом режиме и показать пользователю только некоторое подтверждение, что эта обработка была запущена.

6

Я только что экспериментировал с камнем «delayed_job», потому что он работает с хоринговой платформой Heroku, и это было смешно легко настроить!

Добавить камень в Gemfile, bundle install, rails g delayed_job, rake db:migrate Затем запустите обработчик очереди с;

RAILS_ENV=production script/delayed_job start 

Где у вас есть вызов метода, который является вашим длительным процессом

т.е.
company.send_mail_to_all_users 

изменить его к;

company.delay.send_mail_to_all_users 

Проверить полные документы на GitHub: https://github.com/collectiveidea/delayed_job

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

  • Нет связанных вопросов^_^