Использование fork в Ruby on Rails для создания параллельного процесса - PullRequest
12 голосов
/ 18 января 2012

У меня есть приложение Rails 3, работающее с Passenger на Apache. У меня есть этот код:

class Billing < ActiveRecord::Base
  after_save :sendEmails

  private
    def sendEmails
      fork do 
        UserMailer.clientBilling(self.user, self).deliver
      end
    end
end

В localhost, когда приложение создает биллинг, после его сохранения приложение отправляет электронное письмо пользователю, все работает нормально. Но на сервере, после того как приложение создает биллинг, оно выдает мне ошибки, связанные с гемом MySQL2, такими как «сервер MySQL пропал» или «соединение потеряно», и приложение не отправляет электронные письма. Если я удаляю вилку, она работает нормально, но я хочу использовать вилку, я хочу создать отдельный процесс, потому что это занимает много времени при отправке электронных писем. В чем может быть проблема?

Ответы [ 3 ]

17 голосов
/ 18 января 2012

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

Если вы продолжаете идти по этому пути (и это происходит с подобными тонкостями), тогда вам нужночто-то вроде

::ActiveRecord::Base.clear_all_connections!

перед вилкой и

::ActiveRecord::Base.establish_connection

после.Вам придется делать подобные вещи с такими сервисами, как memcached или mongodb, если вы их используете.

9 голосов
/ 18 января 2012

Будьте предельно осторожны при использовании вил с рельсами / пассажиром, это может стать очень грязным! Вместо этого вы должны использовать resque или delayed_job для этой задачи!

2 голосов
/ 21 марта 2012

Вы можете восстановить соединение внутри вилки:

dbconfig = YAML::load(File.open('your_app_dir/config/database.yml'))
ActiveRecord::Base.establish_connection(dbconfig['development'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...