Tubería rota al usar Python Multiprocessing Managers (BaseManager / SyncManager) para compartir cola con máquinas remotas

En el último mes, tuvimos un problema persistente con el paquete de multiprocesamiento Python 2.6.x cuando intentamos usarlo para compartir una cola entre varias computadoras (linux) diferentes. También le planteé esta pregunta directamente a Jesse Noller, ya que aún no hemos encontrado nada que aclare el problema en StackOverflow, documentos de Python, código fuente o en otro lugar en línea.

Nuestro equipo de ingenieros no ha podido resolver esto, y hemos planteado la pregunta a bastantes personas en grupos de usuarios de Python en vano. Esperaba que alguien pudiera arrojar algo de información, ya que siento que estamos haciendo algo incorrecto pero estamos demasiado cerca del problema para verlo por lo que es.

Aquí está el síntoma:

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

(Estoy mostrando dónde nuestro código llama a queue.get () en un objeto de cola compartido, alojado por un administrador que extiende SyncManger).

Lo peculiar del problema es que si nos conectamos a esta cola compartida en una sola máquina (llamemos a estomachine A), incluso a partir de muchos procesos concurrentes, parece que nunca nos encontramos con un problema. Es solo cuando nos conectamos a la cola (nuevamente, usando una clase que extiende SyncManager multiprocesamiento y actualmente no agrega funcionalidad adicional) desde otras máquinas (llamémoslasmachines B and C) y ejecutar un gran volumen de elementos dentro y fuera de la cola al mismo tiempo que experimentamos un problema.

Es como si el paquete de multiprocesamiento de Python manejara conexiones locales (a pesar de que todavía están usando el mismo método de conexión manager.connect ()) de una manera que funciona desdemachine A pero cuando las conexiones remotas se realizan simultáneamente desde al menos uno demachines B or C Obtenemos un error de tubería rota.

En toda la lectura que hizo mi equipo, pensamos que el problema estaba relacionado con el bloqueo. Pensamos que tal vez no deberíamos usarQueue.Queue, pero en vezmultiprocessing.Queue, pero cambiamos y el problema persistió (también notamos que la Cola compartida de SyncManager es una instancia de Queue.Queue).

Nos estamos sacando el pelo sobre cómo incluso depurar el problema, ya que es difícil de reproducir pero sucede con bastante frecuencia (muchas veces al día si estamos insertando y obteniendo muchos elementos de la cola).

El método que creamosget_from_queue intenta reintentar adquirir el artículo de una cola ~ 10 veces con intervalos de sueño aleatorios, pero parece que si falla una vez, fallará las diez veces (lo que me hace creer que .register () y .connect () ing to un administrador tal vez no le da otra conexión de socket al servidor, pero no pude confirmar esto leyendo los documentos o mirando el código fuente interno de Python).

¿Alguien puede darnos una idea de dónde podríamos mirar o cómo podríamos rastrear lo que realmente está sucediendo?

¿Cómo podemos comenzar una nueva conexión en caso de que se rompa una tubería usandomultiprocessing.BaseManager omultiprocessing.SyncManager?

¿Cómo podemos evitar la tubería rota en primer lugar?

Respuestas a la pregunta(3)

Su respuesta a la pregunta