باستخدام Gevent مع Python XMLRPCLIB
سؤال
هل من الممكن استخدام LIBS XMLRPCLIB القياسي لـ Python مع 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
لتصبح Greenlet المستندة إلى Greenlet ، لذلك سوف يولد مثل هذا الخادم خضراء جديدة لكل اتصال جديد.