Использование gevent с python xmlrpclib - PullRequest
4 голосов
/ 01 ноября 2010

Можно ли использовать стандартные библиотеки Python 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 не исправил сокет, поэтому он блокирует.

1 Ответ

9 голосов
/ 01 ноября 2010

Сокет исправлен, но с вашим кодом есть другие проблемы.

Во-первых, это

def fetch(url):
    g = gevent.spawn(urllib2.urlopen, url)
    return g.get().read()

совпадает с

def fetch(url):
    return urllib2.urlopen(url).read()

Вы создаете новый гринлет здесь, но затем блокируете текущий, пока этот новый не будет сделан. Это не делает вещи параллельными. Это то же самое, что просто запустить urlopen и дождаться его завершения.

Во-вторых, чтобы воспользоваться gevent , должно быть запущено более одной легкой нити (гринлета) одновременно.

SimpleXMLRPCServer, однако, определяется как

class SimpleXMLRPCServer(SocketServer.TCPServer,
                         SimpleXMLRPCDispatcher):

, что означает, что он обслуживает одно соединение за раз.

Если вы создаете свой собственный SimpleXMLRPCServer класс, но используете ThreadingTCPServer вместо TCPServer, вы сможете получить пользу от использования gevent здесь.

monkey.patch_all() исправления threading, чтобы стать на основе greenlet, поэтому такой сервер будет порождать новый greenlet для каждого нового соединения.

...