Использование gevent с python xmlrpclib
Можно ли использовать стандартные библиотеки python xmlrpclib с gevent? В настоящее время я пытаюсь использовать обезьяну.patch_all (), но безуспешно.
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 блокирует сервер. Мне кажется, что это обезьяна.patch_all не залатал сокет, вот почему он блокируется.
1 ответ:
Сокет исправлен нормально, но есть и другие проблемы с вашим кодом.
Во-первых, это
def fetch(url): g = gevent.spawn(urllib2.urlopen, url) return g.get().read()
То же самое, что
def fetch(url): return urllib2.urlopen(url).read()
Вы создаете здесь Новый Зеленый лист, но затем блокируете текущий, пока этот новый не будет завершен. Это не делает вещи параллельными. Это в точности то же самое, что просто запустить urlopen и ждать его завершения.
Во-вторых, чтобы воспользоваться преимуществом gevent , должно быть более одной легкой нити (greenlet) бежать одновременно.SimpleXMLRPCServer, однако, определяется как
Это означает, что он обслуживает одно соединение за раз.class SimpleXMLRPCServer(SocketServer.TCPServer, SimpleXMLRPCDispatcher):
Если вы создадите свой собственный класс
SimpleXMLRPCServer
, но используетеThreadingTCPServer
вместоTCPServer
, Вы сможете извлечь выгоду из использования gevent здесь.
monkey.patch_all()
патчиthreading
, чтобы стать greenlet-based, так что такой сервер будет порождать новый greenlet для каждого нового соединения.