问题描述
我有一个 Rails 3 应用程序与 Apache 上的乘客一起生产.我有这个代码:
I have a Rails 3 app in production with Passenger on Apache. I have this code:
class Billing < ActiveRecord::Base
after_save :sendEmails
private
def sendEmails
fork do
UserMailer.clientBilling(self.user, self).deliver
end
end
end
在 localhost 中,当应用程序创建计费时,保存后,应用程序向用户发送电子邮件,一切正常.但是在服务器中,应用程序创建计费后,它会向我抛出与 gem MySQL2 相关的错误,诸如MySQL 服务器已消失"或连接丢失"之类的错误,并且应用程序不会发送电子邮件.如果我删除 fork 它工作正常,但我想使用 fork,我想创建一个单独的进程,因为发送电子邮件需要很长时间.可能是什么问题?
In localhost, when the app creates a billing, after it is saved, the app sends an email to the user, everything works fine. But in the server, after the app creates a billing, it throws me errors related to the gem MySQL2, errors like "MySQL server has gone away" or "Connection lost", and the app doesn't send the emails. If I remove the fork it works fine, but I want to use fork, I want to create a separated process because it takes to long when sending emails. What could be the problem?
推荐答案
问题是分叉进程继承了其父进程的一些资源,例如其文件描述符.特别是其中一种共享资源是 MySQL 连接.当子进程完成其电子邮件发送并退出时,它会关闭 MySQL 连接,从而关闭父进程连接.
The problem is that a forked process inherits some of its parent's resources, such as its file descriptors. In particular one such shared resource is the MySQL connection. When the child process finishes its email sending and exits it closes the MySQL connection, which closes the parent processes connection.
如果你继续沿着这条路走下去(并且它充满了类似的微妙之处),那么你需要做这样的事情:
If you do continue down this path (and it is frought with similar subtleties) then you need to do something like this:
# Clear existing connections before forking to ensure they do not get inherited.
::ActiveRecord::Base.clear_all_connections!
fork do
# Establish a new connection for each fork.
::ActiveRecord::Base.establish_connection
# The rest of the code for each fork...
end
如果您使用 memcached 或 mongodb 等服务,则必须执行类似的操作.
You'll have to do similar thing with services like memcached or mongodb if you use those.
这篇关于在 Ruby on Rails 中使用 fork 创建并行进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!