2012-01-18 47 views
12

我在使用Apache的Passenger上生产Rails 3应用程序。我有这样的代码:在Ruby on Rails中使用fork来创建并行进程

class Billing < ActiveRecord::Base 
    after_save :sendEmails 

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

在本地主机,当应用程序创建一个结算,它被保存后,该应用程序将电子邮件发送到用户,一切工作正常。但在服务器中,在应用程序创建账单之后,它会抛出与MySQL MySQL相关的错误,“MySQL服务器已经消失”或“连接丢失”等错误,并且应用程序不会发送电子邮件。如果我删除它的工作正常,但我想使用叉,我想创建一个分离的过程,因为它需要很长时间发送电子邮件。可能是什么问题呢?

回答

17

问题是分叉进程继承了它的一些父资源,比如它的文件描述符。特别是一个这样的共享资源是MySQL连接。当子进程完成其电子邮件发送并退出时,它会关闭MySQL连接,从而关闭父进程连接。

如果你继续沿着这条道路(它是frought类似的精妙之处),那么你需要做的是这样

::ActiveRecord::Base.clear_all_connections! 

你之前叉和

::ActiveRecord::Base.establish_connection 

之后。如果你使用这些服务,你必须使用memcached或mongodb等类似的服务。

+0

你知道哪些资源被继承吗?我认为一个流程叉复制整个过程?是不是整个轨道环境再次装上叉子? – 2012-01-22 14:10:00

+1

它复制整个过程,但文件描述符引用完全相同的文件(请参阅fork的手册页) – 2012-01-22 15:26:51

+0

我发现'establish_connection'并不总是必需的,因为ActiveRecord通常会透明地管理它。 – spume 2016-08-31 14:46:29

9

使用铁轨/乘客叉时要格外小心,它会变得非常混乱!相反,您应该使用resque or delayed_job完成此任务!

+2

我用了7天,发现该错误消息“的Mysql ::错误:查询过程中丢失连接到MySQL服务器”和“mysql的错误:: :MySQL服务器已经消失“是使用fork的结果。 – 2013-11-02 00:58:11

2

您可以重新建立叉的内部的连接:

dbconfig = YAML::load(File.open('your_app_dir/config/database.yml')) 
ActiveRecord::Base.establish_connection(dbconfig['development']) 
相关问题