2012-01-18 10 views
12

Tôi có ứng dụng Rails 3 trong sản xuất với Passenger trên Apache. Tôi có mã này:Dùng fork trong Ruby on Rails để tạo quy trình song song

class Billing < ActiveRecord::Base 
    after_save :sendEmails 

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

Trong localhost, khi ứng dụng tạo một thanh toán, sau khi lưu, ứng dụng sẽ gửi email cho người dùng, mọi thứ hoạt động tốt. Nhưng trong máy chủ, sau khi ứng dụng tạo thanh toán, nó ném cho tôi các lỗi liên quan đến đá quý MySQL2, lỗi như "Máy chủ MySQL đã biến mất" hoặc "Mất kết nối" và ứng dụng không gửi email. Nếu tôi loại bỏ các ngã ba nó hoạt động tốt, nhưng tôi muốn sử dụng ngã ba, tôi muốn tạo ra một quá trình tách biệt bởi vì nó cần đến lâu khi gửi email. Điều gì có thể là vấn đề?

Trả lời

17

Vấn đề là quá trình chia nhỏ thừa hưởng một số tài nguyên của cha mẹ, chẳng hạn như các bộ mô tả tệp của nó. Đặc biệt một tài nguyên được chia sẻ như vậy là kết nối MySQL. Khi quá trình con kết thúc việc gửi và thoát email của nó, nó sẽ đóng kết nối MySQL, kết nối này sẽ đóng kết nối các tiến trình cha.

Nếu bạn làm tiếp tục xuống con đường này (và nó là frought với sự tinh tế tương tự) thì bạn cần phải làm điều gì đó như

::ActiveRecord::Base.clear_all_connections! 

Trước khi bạn ngã ba và

::ActiveRecord::Base.establish_connection 

Sau đó. Bạn sẽ phải làm điều tương tự với các dịch vụ như memcached hoặc mongodb nếu bạn sử dụng chúng.

+0

bạn có biết tài nguyên nào được kế thừa không? tôi nghĩ rằng một ngã ba quá trình sao chép toàn bộ quá trình? không phải là toàn bộ môi trường đường ray được nạp lại trên một ngã ba? –

+1

Nó sao chép toàn bộ quá trình, nhưng các bộ mô tả tập tin tham chiếu đến cùng một tập tin (xem trang hướng dẫn sử dụng) –

+0

Tôi thấy rằng 'setup_connection' không phải lúc nào cũng cần thiết vì ActiveRecord thường quản lý minh bạch này. – spume

9

Cẩn thận khi sử dụng nĩa có đường ray/hành khách, nó có thể trở nên rất lộn xộn! Thay vào đó, bạn nên sử dụng resque or delayed_job cho tác vụ này!

+2

tôi mất 7 ngày để khám phá ra rằng msg lỗi "Mysql :: Lỗi: Lost kết nối đến máy chủ MySQL trong truy vấn" và "Mysql :: Lỗi : Máy chủ MySQL đã biến mất "là kết quả của việc sử dụng ngã ba. –

2

Bạn có thể thiết lập lại kết nối bên trong ngã ba:

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