在Ruby on Rails中使用fork来创建并行进程
我在使用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服务器已经消失”或“连接丢失”等错误,并且应用程序不会发送电子邮件。如果我删除它的工作正常,但我想使用叉,我想创建一个分离的过程,因为它需要很长时间发送电子邮件。可能是什么问题呢?
问题是分叉进程继承了它的一些父资源,比如它的文件描述符。特别是一个这样的共享资源是MySQL连接。当子进程完成其电子邮件发送并退出时,它会关闭MySQL连接,从而关闭父进程连接。
如果你继续沿着这条道路(它是frought类似的精妙之处),那么你需要做的是这样
::ActiveRecord::Base.clear_all_connections!
你之前叉和
::ActiveRecord::Base.establish_connection
之后。如果你使用这些服务,你必须使用memcached或mongodb等类似的服务。
使用铁轨/乘客叉时要格外小心,它会变得非常混乱!相反,您应该使用resque or delayed_job完成此任务!
我用了7天,发现该错误消息“的Mysql ::错误:查询过程中丢失连接到MySQL服务器”和“mysql的错误:: :MySQL服务器已经消失“是使用fork的结果。 – 2013-11-02 00:58:11
您可以重新建立叉的内部的连接:
dbconfig = YAML::load(File.open('your_app_dir/config/database.yml'))
ActiveRecord::Base.establish_connection(dbconfig['development'])
你知道哪些资源被继承吗?我认为一个流程叉复制整个过程?是不是整个轨道环境再次装上叉子? – 2012-01-22 14:10:00
它复制整个过程,但文件描述符引用完全相同的文件(请参阅fork的手册页) – 2012-01-22 15:26:51
我发现'establish_connection'并不总是必需的,因为ActiveRecord通常会透明地管理它。 – spume 2016-08-31 14:46:29