2011-11-04 8 views
6

chúng tôi sử dụng Rails và EventMachine cùng nhau, và khi sử dụng combo đó với Passenger, có một số thiết lập rất cụ thể cần được thực hiện. Sau rất nhiều thử nghiệm và lỗi, tôi đã khởi tạo EventMachine hoạt động tốt, nhưng tôi muốn hiểu mã tốt hơn một chút. Như bạn có thể thấy bên dưới trong đoạn mã này, trình khởi tạo của chúng tôi kiểm tra Hành khách và sau đó kiểm tra xem đó có phải là quá trình được chia nhỏ trước khi khởi động lại EventMachine hay không.EventMachine và Ruby Threads - những gì thực sự đang diễn ra ở đây?

if defined?(PhusionPassenger) 
    PhusionPassenger.on_event(:starting_worker_process) do |forked| 
    # for passenger, we need to avoid orphaned threads 
    if forked && EM.reactor_running? 
     EM.stop 
    end 
    Thread.new { 
     EM.run do 

Câu hỏi của tôi liên quan đến EM.reactor_running? và lệnh EM.stop. Nếu Hành khách đã chia rẽ quy trình của chúng tôi, tại sao tôi cần phải khởi động lại tham chiếu EM trong một chuỗi mới? Nếu EM.reactor_running? trả về true, cá thể EM nào tôi đang tham chiếu?

Bạn có thể xem mã khởi tạo đầy đủ trên blog của chúng tôi tại đây http://www.hiringthing.com/2011/11/04/eventmachine-with-rails.html

Trả lời

13

Trước hết, chỉ có một EventMachine dụ cho mỗi quá trình Ruby, vì vậy không có vấn đề gì bạn sẽ luôn tham khảo cùng dụ EM, không phụ thuộc vào chỉ hiện tại của bạn.

Bạn chạy lò phản ứng trong một chuỗi mới, riêng biệt để không chặn luồng chính (mục đích của nó là phục vụ yêu cầu web). EM.run nếu không sẽ kiểm soát, nhập vào vòng lặp chạy của nó, không rời khỏi khối EM.run nữa. EM.reactor_running? trả về đúng, tốt, nếu một vòng lặp EM đang chạy ở đâu đó. Vì chỉ có một cho mỗi quá trình Ruby, nó đủ dễ dàng cho phương pháp để tìm ra nếu EM đang chạy hay không.

Thiết lập bạn có ở đây là cách đơn giản nhất để sử dụng EM bên trong một quy trình Ruby bình thường mà không can thiệp vào mọi thứ khác đang chạy. Tôi giả sử bạn đang đẩy tin nhắn đến một nhà môi giới AMQP từ ứng dụng web của bạn. Bất cứ khi nào bạn gửi một tin nhắn, nó sẽ đi vào vòng lặp chạy của EM trong thread riêng biệt, phần đó là khá minh bạch cho bạn, và không ảnh hưởng đến vòng lặp chính, mà có thể tiếp tục xử lý yêu cầu web Rails. Hãy cẩn thận mặc dù luôn đẩy mọi thứ vào vòng lặp EM bằng EM.next_tick. Cố gắng xử lý các ổ cắm được mở bởi EM trong các chủ đề khác nhau có thể dẫn đến những điều xấu xảy ra, mà tôi đã thấy trong sản xuất, tình cờ bằng cách sử dụng và xây dựng một thư viện gọi là đang xảy ra;)

Dừng vòng EM trước khi bắt đầu một vòng mới của một vòng lặp EM có thể bị bỏ qua từ một tiến trình cha, điều này có thể dẫn đến các vấn đề với các bộ mô tả tập tin được mở, sử dụng EM, trong tiến trình cha. Trong mã tùy chỉnh, điều này có thể được phá vỡ bằng cách sử dụng EM.fork_reactor, nhưng khi tiến trình cha mẹ nằm ngoài tầm kiểm soát của bạn, nó là an toàn nhất để kiểm tra xem một lò phản ứng có tồn tại và dừng nó trước khi bắt đầu một cá thể mới hay không.

+0

Cảm ơn mô tả tuyệt vời. Tôi rõ ràng về sự cần thiết để chạy EM trong thread riêng của nó, nhưng Khi bạn nói "EM loop có thể được còn lại", đó là nơi tôi là một chút không rõ ràng. Làm thế nào để một vòng lặp EM nhận được "còn sót lại"? Tôi không tắt quá trình cha mẹ 'EM, đúng không? – Joshua

+0

Đó chính xác là những gì bạn đang làm. Bạn đang tắt một EM có khả năng còn sót lại từ quá trình cha mẹ. Nếu một vòng lặp EM chạy trong quá trình cha mẹ, nó sẽ được chia rẽ quá, nhưng bạn thường không phải ở tất cả các quan tâm đến các mô tả tập tin còn lại từ cha mẹ, vì vậy bạn bắt đầu từ đầu thay thế. Cho rằng Hành khách không thể chạy một vòng lặp EM bởi chính nó, đây là một biện pháp an toàn hơn bất cứ điều gì khác. – roidrage

+0

Trong một mạch tương tự, tôi đang làm việc với RabbitMQ thông qua đá quý ruby-amqp, trong một ứng dụng websocket chạy dưới dạng mỏng. Thin có vòng lặp EventMachine riêng của nó, và tôi hiện đang sử dụng EventMachine.next_tick để đột nhập và làm công cụ amqp của tôi. Đây có phải là chính xác hoặc tôi nên sử dụng EventMachine.fork_reactor để cung cấp cho AMQP EM của riêng nó để sử dụng? – wchrisjohnson