2011-05-18 22 views
5

Considere el siguiente código:construir un simple despachador remoto usando multiprocessing.Managers

Servidor:

import sys 
from multiprocessing.managers import BaseManager, BaseProxy, Process 

def baz(aa) : 
    l = [] 
    for i in range(3) : 
     l.append(aa) 
    return l 

class SolverManager(BaseManager): pass 

class MyProxy(BaseProxy): pass 

manager = SolverManager(address=('127.0.0.1', 50000), authkey='mpm') 
manager.register('solver', callable=baz, proxytype=MyProxy) 

def serve_forever(server): 
    try : 
     server.serve_forever() 
    except KeyboardInterrupt: 
     pass 

def runpool(n): 
    server = manager.get_server() 
    workers = [] 

    for i in range(int(n)): 
     Process(target=serve_forever, args=(server,)).start() 

if __name__ == '__main__': 
    runpool(sys.argv[1]) 

Cliente:

import sys 
from multiprocessing.managers import BaseManager, BaseProxy 

import multiprocessing, logging 

class SolverManager(BaseManager): pass 

class MyProxy(BaseProxy): pass 

def main(args) : 
    SolverManager.register('solver') 
    m = SolverManager(address=('127.0.0.1', 50000), authkey='mpm') 
    m.connect() 

    print m.solver(args[1])._getvalue() 

if __name__ == '__main__': 
    sys.exit(main(sys.argv)) 

Si funciono con el servidor utilizando sólo un proceso como python server.py 1

luego el cliente funciona como se esperaba. Pero si desovar dos procesos (python server.py 2) escuchando las conexiones, me sale un error desagradable:

$python client.py ping 
Traceback (most recent call last): 
    File "client.py", line 24, in <module> 
sys.exit(main(sys.argv)) 
    File "client.py", line 21, in main 
    print m.solver(args[1])._getvalue() 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 637, in temp 
    authkey=self._authkey, exposed=exp 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 894, in AutoProxy 
    incref=incref) 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 700, in __init__ 
    self._incref() 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 750, in _incref 
    dispatch(conn, None, 'incref', (self._id,)) 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 79, in dispatch 
    raise convert_to_error(kind, result) 
multiprocessing.managers.RemoteError: 
--------------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 181, in handle_request 
    result = func(c, *args, **kwds) 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 402, in incref 
    self.id_to_refcount[ident] += 1 
KeyError: '7fb51084c518' 
--------------------------------------------------------------------------- 

Mi idea es bastante simple. Quiero crear un servidor que generará una cantidad de trabajadores que compartirán el mismo socket y manejarán las solicitudes de manera independiente. Tal vez estoy usando la herramienta equivocada aquí?

El objetivo es construir una estructura de 3 niveles, donde todas las peticiones son manejadas a través de un servidor HTTP y luego enviados a los nodos que se sientan en un clúster y de los nodos a los trabajadores a través de los gestores de multiprocesamiento ...

Hay un servidor público, un nodo por máquina y x número de trabajadores en cada máquina, dependiendo de la cantidad de núcleos ... Sé que puedo usar una biblioteca más sofisticada, pero para una tarea tan simple (solo estoy creando prototipos aquí) simplemente usaría la biblioteca de multiprocesamiento ... ¿Es posible o debería explorar directamente otras soluciones? Siento que estoy muy cerca de tener algo trabajando aquí ... gracias.

Respuesta

1


Usted está tratando de inventar una rueda, muchos han inventado antes.

Me parece que está buscando una cola de tareas donde su servidor envía tareas a, y sus trabajadores ejecutan estas tareas.

Yo recomendaría que eche un vistazo a Celery.

Cuestiones relacionadas