2010-09-06 31 views
13

Trong tháng trước, chúng tôi đã gặp sự cố liên tục với gói đa xử lý Python 2.6.x khi chúng tôi cố gắng sử dụng nó chia sẻ một hàng đợi giữa các máy tính (linux) khác nhau. Tôi đã đặt câu hỏi này trực tiếp cho Jesse Noller cũng như vì chúng tôi chưa tìm thấy bất kỳ điều gì làm sáng tỏ vấn đề trên StackOverflow, tài liệu Python, mã nguồn hoặc ở nơi khác trực tuyến.Ống bị hỏng khi sử dụng các trình quản lý đa xử lý Python (BaseManager/SyncManager) để chia sẻ hàng đợi với các máy từ xa

Nhóm kỹ sư của chúng tôi đã không thể giải quyết vấn đề này và chúng tôi đã đặt câu hỏi cho một số người trong nhóm người dùng trăn không có kết quả. Tôi đã hy vọng một người nào đó có thể làm sáng tỏ một số thông tin, vì tôi cảm thấy như chúng tôi đang làm điều gì đó không chính xác nhưng quá gần với vấn đề để xem nó là gì.

Dưới đây là các triệu chứng:

Traceback (most recent call last): 
    File "/var/django_root/dev/com/brightscope/data/processes/daemons/deferredupdates/servers/queue_server.py", line 65, in get_from_queue 
    return queue, queue.get(block=False) 
    File "<string>", line 2, in get 
    File "/usr/local/lib/python2.6/multiprocessing/managers.py", line 725, in _callmethod 
    conn.send((self._id, methodname, args, kwds)) 
IOError: [Errno 32] Broken pipe 

(Tôi thấy nơi mã của chúng tôi gọi queue.get() trên một đối tượng hàng đợi được chia sẻ, được tổ chức bởi một người quản lý kéo dài SyncManger).

Điều đặc biệt về vấn đề là nếu chúng ta kết nối với hàng đợi được chia sẻ này trên một máy duy nhất (hãy gọi machine A) này, thậm chí từ rất nhiều quy trình đồng thời, dường như chúng ta chưa bao giờ gặp phải vấn đề. Chỉ khi chúng ta kết nối với hàng đợi (một lần nữa, sử dụng một lớp mở rộng đa xử lý SyncManager và hiện không bổ sung thêm chức năng nào) từ các máy khác (hãy gọi những số này machines B and C) và chạy một khối lượng lớn các mục vào và ra khỏi hàng đợi tại cùng một thời gian mà chúng tôi gặp phải sự cố.

Nó giống như gói đa xử lý của python xử lý các kết nối cục bộ (mặc dù chúng vẫn đang sử dụng cùng phương thức kết nối manager.connect()) theo cách hoạt động từ machine A nhưng khi kết nối từ xa được thực hiện đồng thời từ ít nhất một trong machines B or C chúng tôi gặp lỗi hỏng ống.

Trong tất cả việc đọc nhóm của tôi đã làm, chúng tôi nghĩ rằng vấn đề có liên quan đến khóa. Chúng tôi nghĩ có lẽ chúng ta không nên sử dụng Queue.Queue, nhưng thay vào đó là multiprocessing.Queue, nhưng chúng tôi đã chuyển sang và sự cố vẫn tiếp diễn (chúng tôi cũng nhận thấy Hàng đợi được chia sẻ của SyncManager là một phiên bản của Queue.Queue).

Chúng tôi đang cố gắng giải quyết vấn đề, vì rất khó để tái sản xuất nhưng xảy ra khá thường xuyên (nhiều lần mỗi ngày nếu chúng tôi chèn và .get() ing nhiều mục từ hàng đợi) .

Phương pháp chúng tôi tạo get_from_queue cố gắng thử lại mục từ hàng đợi ~ 10 lần với khoảng thời gian ngủ ngẫu nhiên, nhưng có vẻ như không thành công một lần, nó sẽ thất bại cả mười lần (dẫn tôi tin rằng .register() và .connect() ing vào một người quản lý có lẽ không cung cấp kết nối socket khác cho máy chủ, nhưng tôi không thể xác nhận điều này bằng cách đọc tài liệu hoặc xem mã nguồn nội bộ Python).

Có ai có thể cung cấp bất kỳ thông tin chi tiết nào về nơi chúng tôi có thể xem hoặc cách chúng tôi có thể theo dõi những gì đang thực sự xảy ra không?

Làm cách nào để chúng tôi có thể bắt đầu kết nối mới trong trường hợp ống bị hỏng bằng cách sử dụng multiprocessing.BaseManager hoặc multiprocessing.SyncManager?

Làm cách nào chúng ta có thể ngăn chặn đường ống bị hỏng ở nơi đầu tiên?

+0

Tôi đã gặp phải vấn đề tương tự, trong trường hợp của tôi, đó là do lỗi khi chương trình chính thoát quá sớm và đa xử lý. Các cá thể xử lý vẫn chạy trong nền. – purrogrammer

Trả lời

9

FYI Trong trường hợp bất kỳ ai khác chạy cùng lỗi này, sau khi tư vấn rộng rãi với Ask Solem và Jesse Noller của nhóm dev cốt lõi của Python, có vẻ như đây thực sự là lỗi trong python 2.6.x hiện tại (và có thể 2.7+ và có thể là 3.x).Họ đang xem xét các giải pháp khả thi và sửa chữa có thể sẽ được đưa vào một phiên bản tương lai của Python.

+18

Có báo cáo lỗi Python cho việc này không? –

7

Tôi đã gặp phải vấn đề tương tự, ngay cả khi kết nối trên máy chủ cục bộ trong python 2.7.1. Sau một ngày gỡ lỗi, tôi đã tìm thấy nguyên nhân và giải pháp thay thế:

Nguyên nhân: Lớp BaseProxy có lưu trữ cục bộ luồng lưu trữ kết nối, được sử dụng lại cho các kết nối trong tương lai gây ra lỗi "hỏng ống" ngay cả khi tạo Trình quản lý mới

Cách giải quyết: Xóa kết nối lưu trữ trước khi kết nối

if address in BaseProxy._address_to_local: 
    del BaseProxy._address_to_local[address][0].connection 
+0

Điều này cũng làm việc cho tôi. –

+0

Tôi nên thêm thay đổi này vào tệp/dòng nào? –

+0

Tôi cũng đang cố hiểu điều này. Địa chỉ đến từ đâu? – mudda

0

Ngoài ra bạn có thể thử để bắt ngoại lệ trong tiến trình con, để nó không nên cố gắng để đóng kết nối UN-dự kiến. Tương tự như vậy đã xảy ra với tôi và cuối cùng tôi đã phải ngăn chặn các lỗi để các đường ống không nên đến gần bất ngờ.

Các vấn đề liên quan