En utilisant gevent avec python xmlrpclib
Question
Est-il possible d'utiliser la norme libs python xmlrpclib avec gevent? Actuellement, je suis essayé d'utiliser monkey.patch_all (), mais sans succès.
from gevent import monkey
monkey.patch_all()
import gevent
import time
import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer
import urllib2
def fetch(url):
g = gevent.spawn(urllib2.urlopen, url)
return g.get().read()
def is_even(n):
return n%2 == 0
def req(url):
return fetch(url)
server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(is_even, "is_even")
server.register_function(req, "req")
server.serve_forever()
urllib2.urlopen est serveur de blocage. Il me semble que monkey.patch_all n'a pas prise patché, voilà pourquoi il bloque.
La solution
La prise est patché très bien, mais il y a d'autres problèmes avec votre code.
Tout d'abord, cette
def fetch(url):
g = gevent.spawn(urllib2.urlopen, url)
return g.get().read()
est le même que
def fetch(url):
return urllib2.urlopen(url).read()
Vous fraie un nouveau Greenlet ici mais bloquant l'actuel jusqu'à ce nouveau se fait. Il ne fait pas les choses en même temps. Il est exactement la même chose que d'exécuter simplement urlopen et d'attendre à la fin.
En second lieu, afin de tirer profit de gevent il faut que ce soit plus d'un fil léger (Greenlet) en cours d'exécution en même temps.
SimpleXMLRPCServer, cependant, est défini comme étant
class SimpleXMLRPCServer(SocketServer.TCPServer,
SimpleXMLRPCDispatcher):
ce qui veut dire qu'il dessert une connexion à la fois.
Si vous faites votre propre classe SimpleXMLRPCServer
, mais l'utilisation ThreadingTCPServer
au lieu de TCPServer
, vous devriez être en mesure de bénéficier de l'utilisation gevent ici.
monkey.patch_all()
patches threading
pour devenir base Greenlet, donc ce serveur frayer un nouveau Greenlet pour chaque nouvelle connexion.