2009-10-14 10 views
6

Tôi muốn một số suy nghĩ về việc sử dụng fork {} để 'nền' một quá trình từ một ứng dụng đường ray là một ý tưởng hay ...sử dụng hạt nhân # ngã ba cho quá trình nền, thuận? khuyết điểm?

Từ những gì tôi thu thập ngã ba {my_method; Quá trình # setsid} thực tế làm những gì nó phải làm.

1) tạo ra một quá trình với một PID khác nhau

2) không làm gián đoạn quá trình gọi điện thoại (ví dụ như nó tiếp tục w/o chờ ngã ba để kết thúc)

3) thực hiện cho đến khi đứa trẻ nó kết thúc

.. điều gì tuyệt vời, nhưng đó có phải là một ý tưởng hay không? Chính xác là cái nĩa đang làm gì? Liệu nó tạo ra một trường hợp trùng lặp của toàn bộ đường ray của tôi mongrel/hành khách dụ trong bộ nhớ? Nếu vậy thì sẽ rất tệ. Hay, bằng cách nào đó, nó làm điều đó mà không tốn nhiều bộ nhớ.

Mục tiêu cuối cùng của tôi là xóa bỏ nền hệ thống/hàng đợi nền của tôi để ủng hộ các quy trình này (chủ yếu là gửi email) - nhưng nếu điều này không tiết kiệm được bộ nhớ thì chắc chắn là một bước sai hướng

+0

Tôi sẽ gắn bó với hệ thống xếp hàng. Nếu bạn đang sử dụng một gói được duy trì tốt cho điều này, bạn sẽ không phải lo lắng về việc khai thác bom nĩa và nhiều chi tiết khác cần thiết cho một hệ thống xếp hàng tốt. Đây là một trường hợp bạn nên cẩn thận khi lăn mã của riêng bạn trừ khi có nhu cầu rõ ràng để làm như vậy. –

+0

xếp hàng máy chủ ++. Có thể muốn kiểm tra MQ (http://github.com/mdarby/mq) để xếp hàng email. Tôi đã sử dụng nó trong sản xuất trong nhiều tháng mà không có vấn đề gì. –

Trả lời

0

Ngữ nghĩa của ngã ba là sao chép toàn bộ không gian bộ nhớ của tiến trình vào một quy trình mới, nhưng nhiều hệ thống (nhiều nhất) sẽ làm điều đó bằng cách chỉ tạo một bản sao của các bảng bộ nhớ ảo và đánh dấu nó sao chép. Điều đó có nghĩa rằng (lúc đầu, ít nhất) nó không sử dụng nhiều bộ nhớ vật lý hơn, chỉ đủ để làm cho các bảng mới và các cấu trúc dữ liệu cho mỗi quá trình khác.

Điều đó nói rằng, tôi không chắc là Ruby, RoR, vv tương tác như thế nào với tính năng ghi chép sao chép. Trong bộ sưu tập rác cụ thể có thể có vấn đề nếu nó chạm vào nhiều trang bộ nhớ (khiến chúng được sao chép).

+0

Tôi đã nghe cả hai thứ về COW ... khá chắc chắn một số chi nhánh 1.8 không hỗ trợ nó, nhưng REE thực hiện (?). Và tôi đã nghe cả 1.9 và không hỗ trợ COW. Điều đó nói rằng, * ngay cả khi nó không *, hãy tưởng tượng hành động đường ray của tôi: def foo do_stuff fork_and_send_email do_more_stuff cuối ngay cả khi COW ngã ba sẽ không phải là vị trí bộ nhớ ban đầu được thay đổi ngay lập tức (vì những gì đến sau nó) và do đó kích động một bản sao? Ngay cả khi ngã ba là cuộc gọi phương thức cuối cùng. Tôi muốn tưởng tượng đường ray vẫn làm những thứ sau đó, chưa kể đến ... yêu cầu tiếp theo đến trong cùng một quá trình. jsharpe

+0

xác nhận quyền sở hữu, định dạng nhận xét: def foo; do_stuff; fork_and_send_email; do_more_stuff; end – jsharpe

+0

Vâng, có, một số sao chép sẽ xảy ra, nhưng hy vọng nó sẽ không phải là toàn bộ không gian bộ nhớ của quá trình; thay vào đó nó sẽ là các trang bộ nhớ riêng lẻ ở đây và ở đó (trên các trang bộ nhớ x86 thường là 4 kilobyte). – wdebeaum

4

Ngã ba tạo bản sao cho toàn bộ quá trình của bạn và tùy thuộc vào cách bạn kết nối với máy chủ ứng dụng, bản sao của nó cũng vậy. Như đã lưu ý trong các cuộc thảo luận khác, việc này được thực hiện với sao chép-trên-ghi để nó có thể chấp nhận được. Unix được xây dựng xung quanh ngã ba (2), sau khi tất cả, vì vậy nó phải quản lý nó khá nhanh. Lưu ý rằng bất kỳ phần đệm I/O được đệm một phần nào, các tệp đang mở và nhiều thứ khác cũng được sao chép, cũng như trạng thái của chương trình được tải xuống để ghi chúng ra, điều này sẽ không chính xác.

tôi có một vài suy nghĩ:

  • Bạn đang sử dụng Action Mailer? Có vẻ như email sẽ dễ dàng được thực hiện với AM hoặc theo số Process.popen của một cái gì đó. (Popen sẽ làm một cái nĩa, nhưng ngay sau đó là một người thực hiện.)
  • ngay lập tức loại bỏ tất cả trạng thái đó bằng cách thực hiện Process.exec của một trình thông dịch ruby ​​khác cùng với chức năng của bạn. Nếu có quá nhiều trạng thái để chuyển hoặc bạn thực sự cần phải sử dụng các mô tả tệp trùng lặp đó, bạn có thể làm một cái gì đó như IO#popen thay vì vậy bạn có thể gửi công việc xử lý con để làm. Hệ thống sẽ chia sẻ các trang chứa văn bản của trình thông dịch Ruby của tiến trình con với cha mẹ một cách tự động.
  • ngoài những điều trên, bạn có thể muốn xem xét việc sử dụng đá quý daemons. Trong khi quá trình rails của bạn đã là một daemon, sử dụng gem có thể làm cho nó dễ dàng hơn để giữ một tác vụ nền chạy như một máy chủ lệnh batch và làm cho nó dễ dàng khởi động, theo dõi, khởi động lại nếu nó bom, và tắt khi bạn thực hiện .. .
  • nếu bạn làm lối ra từ một tiến trình con fork(2) ed, sử dụng exit! thay vì exit
  • có một hàng đợi thông điệp và một daemon đã được thiết lập, giống như bạn làm thế, kinda âm thanh như một giải pháp tốt đối với tôi :-)
1

Lưu ý rằng nó sẽ ngăn bạn sử dụng JRuby trên Rails vì fork() chưa được triển khai (chưa).