2012-01-18 82 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']) 
相關問題