Broken Pipe bei Verwendung von Python Multiprocessing Managers (BaseManager / SyncManager) zum Freigeben der Warteschlange für Remote-Computer

Im letzten Monat hatten wir ein anhaltendes Problem mit dem Python 2.6.x-Multiprozessor-Paket, als wir versuchten, eine Warteschlange für mehrere verschiedene (Linux-) Computer freizugeben. Ich habe diese Frage auch Jesse Noller direkt gestellt, da wir noch nichts gefunden haben, was das Problem in StackOverflow, Python-Dokumenten, Quellcode oder anderen Online-Quellen verdeutlicht.

Unser Ingenieurteam konnte dieses Problem nicht lösen, und wir haben die Frage einigen Personen in Python-Benutzergruppen ohne Erfolg gestellt. Ich hatte gehofft, jemand könnte etwas Einsicht gewinnen, da ich das Gefühl habe, dass wir etwas Falsches tun, aber dem Problem zu nahe sind, um es so zu sehen, wie es ist.

Hier ist das Symptom:

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

(Ich zeige, wo unser Code queue.get () in einem gemeinsam genutzten Warteschlangenobjekt aufruft, das von einem Manager gehostet wird, der SyncManger erweitert.)

Das Besondere an diesem Problem ist, dass, wenn wir auf einem einzelnen Computer eine Verbindung zu dieser freigegebenen Warteschlange herstellen (nennen wir diesmachine A) Auch bei vielen gleichzeitigen Prozessen scheint es nie zu einem Problem zu kommen. Es ist nur, wenn wir eine Verbindung mit der Warteschlange herstellen (wieder unter Verwendung einer Klasse, die den Multiprocessing-SyncManager erweitert und derzeit keine zusätzlichen Funktionen hinzufügt), von anderen Maschinen (nennen wir diesemachines B and C) und führen Sie eine große Anzahl von Elementen in die Warteschlange ein und aus, während ein Problem auftritt.

Es ist, als ob das Multiprocessing-Paket von Python lokale Verbindungen verarbeitet (obwohl sie immer noch dieselbe Verbindungsmethode manager.connect () verwenden), und zwar auf eine Weise, die von @ aus funktioniermachine A, aber wenn gleichzeitig Remoteverbindungen von mindestens einem von @ hergestellt werdmachines B or C Es wird ein Fehler aufgrund eines Rohrbruchs angezeigt.

Bei der gesamten Lektüre, die mein Team durchgeführt hat, dachten wir, dass das Problem mit dem Sperren zusammenhängt. Wir dachten, vielleicht sollten wir nicht @ verwendQueue.Queue, aber stattdessenmultiprocessing.Queue, aber wir haben gewechselt und das Problem blieb bestehen (wir haben auch festgestellt, dass die eigene freigegebene Warteschlange von SyncManager eine Instanz von Queue.Queue ist).

Wir haben uns die Mühe gemacht, das Problem zu beheben, da es schwer zu reproduzieren ist, aber ziemlich häufig vorkommt (viele Male pro Tag, wenn wir viele Elemente aus der Warteschlange einfügen und .get () entfernen).

Die Methode, die wir erstellt habenget_from_queue versucht erneut, das Element ~ 10 Mal mit zufälligen Ruheintervallen aus einer Warteschlange abzurufen. Wenn es jedoch einmal fehlschlägt, schlägt es alle zehn Mal fehl (was mich zu der Annahme veranlasst, dass .register () und .connect () fehlschlagen an einen Manager gibt es vielleicht keine andere Socket-Verbindung zum Server, aber ich konnte dies weder durch Lesen der Dokumentation noch durch Betrachten des internen Python-Quellcodes bestätige

Kann jemand einen Einblick geben, wo wir suchen oder wie wir verfolgen können, was tatsächlich passiert?

Wie können wir bei einem Rohrbruch mit @ eine neue Verbindung herstellemultiprocessing.BaseManager odermultiprocessing.SyncManager?

Wie können wir den Rohrbruch überhaupt verhindern?

Antworten auf die Frage(6)

Ihre Antwort auf die Frage