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

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
4b9b3361

Ответ 2

Начните отдельный процесс, который, вероятно, легче всего сделать с помощью system, добавив "nohup" и добавив "&" до конца команды, которую вы передаете. (Убедитесь, что команда представляет собой только один строковый аргумент, а не список аргументов.)

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

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

  • Если вы запускаете программу с другим именем, она легко идентифицируется в "ps", поэтому вы не ошибаетесь, полагая, что FastCGI back-end удалился или что-то еще, и убейте его.

Действительно, процесс, который вы начинаете, должен быть "деамонизирован", обратитесь за помощью к Daemonize.

Ответ 3

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

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

RAILS_ENV=production script/delayed_job start

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

company.send_mail_to_all_users

вы меняете его на;

company.delay.send_mail_to_all_users

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

Ответ 7

Как насчет:

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, имея возможность доступа к базе данных.