Utilizzando gevent con pitone xmlrpclib
Domanda
E 'possibile usare librerie standard di xmlrpclib di pitone con gevent? Attualmente sto provato ad utilizzare monkey.patch_all (), ma senza successo.
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 sta bloccando server. Sembra a me, che monkey.patch_all non patchato presa, è per questo che i blocchi.
Soluzione
La presa è patchato bene, ma ci sono altri problemi con il vostro codice.
In primo luogo, questo
def fetch(url):
g = gevent.spawn(urllib2.urlopen, url)
return g.get().read()
è lo stesso di
def fetch(url):
return urllib2.urlopen(url).read()
Si sta generando una nuova greenlet qui, ma poi bloccando quello attuale fino a quella nuova è fatto. Non fa cose concorrente. E 'esattamente lo stesso solo in esecuzione urlopen e in attesa che finisca.
In secondo luogo, al fine di trarre vantaggio da gevent ci avuto modo di essere più di un filo leggero (greenlet) in esecuzione allo stesso tempo.
SimpleXMLRPCServer, tuttavia, è definito come
class SimpleXMLRPCServer(SocketServer.TCPServer,
SimpleXMLRPCDispatcher):
che significa che serve una connessione alla volta.
Se si effettua la propria classe SimpleXMLRPCServer
, ma l'uso ThreadingTCPServer
invece di TCPServer
, si dovrebbe essere in grado di trarre vantaggio dall'uso gevent qui.
monkey.patch_all()
patch threading
a diventare greenlet-based, in modo tale server generare una nuova greenlet per ogni nuova connessione.