Использование Gevent с Python XMLRPCLIB
Вопрос
Можно ли использовать стандарт Python Libs XMLRPClib с Gevent? В настоящее время я пытался использовать monkey.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 - блокирующий сервер. Это выглядит для меня, что monkey.patch_all не запланировал сокет, поэтому он блокирует.
Решение
Гнездо пропатан штраф, но есть и другие проблемы с вашим кодом.
Во-первых, это
def fetch(url):
g = gevent.spawn(urllib2.urlopen, url)
return g.get().read()
такой же как
def fetch(url):
return urllib2.urlopen(url).read()
Вы неренируете новую зелечую здесь, но затем блокируя текущий, пока этот новый не будет сделан. Это не делает вещи одновременно. Это точно так же, как просто запустить Urlopen и ждать его до конца.
Во-вторых, чтобы воспользоваться завещание Там приходилось быть более одной легкой нитью (зелени) одновременно.
SimplexMLRPCServer, однако, определяется как
class SimpleXMLRPCServer(SocketServer.TCPServer,
SimpleXMLRPCDispatcher):
Что означает, что он служит одно соединение за раз.
Если вы сделаете свой собственный SimpleXMLRPCServer
класс, но использовать ThreadingTCPServer
вместо TCPServer
, Вы должны быть в состоянии воспользоваться использованием Gevent здесь.
monkey.patch_all()
патчи threading
Чтобы стать зеленым, поэтому такой сервер будет порождать новый зеленый лес для каждой новой связи.