Python xmlrpclibでGeventを使用します
質問
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を実行して終了するのを待っているのとまったく同じです。
第二に、利用するために Gevent 複数の軽量スレッド(Greenlet)が同時に実行される必要がありました。
ただし、SimplexmlrpcServerは次のように定義されています
class SimpleXMLRPCServer(SocketServer.TCPServer,
SimpleXMLRPCDispatcher):
つまり、一度に1つの接続を提供します。
あなたがあなた自身を作るなら SimpleXMLRPCServer
クラスですが、使用します ThreadingTCPServer
それ以外の TCPServer
, 、ここでGeventを使用することで恩恵を受けることができるはずです。
monkey.patch_all()
パッチ threading
Greenletベースになるために、このようなサーバーは、新しい接続ごとに新しいGreenletを生成します。
所属していません StackOverflow