Considérez le code suivant:construire simple répartiteur à distance à l'aide multiprocessing.Managers
Serveur:
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])
Client:
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 je lance le serveur en utilisant un seul processus que python server.py 1
alors le client fonctionne comme prévu. Mais si je Spawn deux processus (python server.py 2
) l'écoute des connexions, je reçois une erreur méchant:
$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'
---------------------------------------------------------------------------
Mon idée est assez simple. Je veux créer un serveur qui engendrera un certain nombre de travailleurs qui partageront le même socket et géreront les demandes indépendamment. Peut-être que j'utilise le mauvais outil ici?
L'objectif est de construire une structure à 3 niveaux où toutes les demandes sont traitées via un serveur HTTP, puis envoyés vers des noeuds assis dans un cluster et de nœuds aux travailleurs par les gestionnaires de multitraitement ...
Il y a un serveur public, un nœud par machine et x nombre de travailleurs sur chaque machine en fonction du nombre de cœurs ... Je sais que je peux utiliser une bibliothèque plus sophistiquée, mais pour une tâche si simple (je ne fais que prototyper ici) j'utiliserais simplement la bibliothèque multi-traitement ... Est-ce possible ou devrais-je explorer directement d'autres solutions? Je sens que je suis très proche d'avoir quelque chose qui fonctionne ici ... merci.