/ / Python。竜巻。ノンブロッキングxmlrpcクライアント - python、xml-rpc、トルネード、xmlrpclib

Python。竜巻。ノンブロッキングxmlrpcクライアント - Python、xml-rpc、tornado、xmlrpclib

基本的には次のようにxmlrpcハンドラを呼び出すことができます。

import xmlrpclib
s = xmlrpclib.ServerProxy("http://remote_host/rpc/")
print s.system.listmethods()

竜巻では、このように統合することができます。

import xmlrpclib
import tornado.web

s = xmlrpclib.ServerProxy("http://remote_host/rpc/")

class MyHandler(tornado.web.RequestHandler):
def get(self):
result = s.system.listmethods()

私は次のような質問を少し持っています。

  1. 意志 result = s.system.listmethods() ブロック竜巻?
  2. 非ブロッキングのxmlrpcクライアントはありますか?
  3. どうやって達成できますか result = yield gen.Task(s.system.listmethods)

回答:

回答№1の場合は3

1. xmlrpclibはpythonソケットのブロックを使用しているため、竜巻をブロックします。

2.気づいていませんが、xmlrpclibを保持しながら非同期にすることができるソリューションを提供します。

3.私の解決策はトルネードgenを使用しません。

それで、「ネットワーキングをしていて非同期コードを書く必要があるときはいつでも気にする必要がある便利なライブラリが1つあります。それは、私にはみんなにお勧めする、非常に高品質のライブラリです。

なぜそれが良くて使いやすいのですか?

  • 非同期コードを同期的に記述することができます(それにより、簡単になります)。
  • あなたがしなければならないのは、そうするために1つの単純な行を持つサルパッチです。

    gevent輸入猿から。 monkey.patch_all()

竜巻を使用するときは、2つのことを知っておく必要があります(あなたがすでに知っているかもしれません)。

  • HTTPServerとして機能する場合、Tornadoは非同期ビューのみをサポートします(非同期ビューではWSGIはサポートされません)
  • 非同期ビューは自分自身で応答を終了させる必要があります(self.finish()またはself.render()(self.finish()を呼び出す)を使用して行います。

それでは、ここに必要なものと竜巻との必要なgevent統合を説明する例があります。

# Python immports
import functools

# Tornado imports
import tornado.ioloop
import tornado.web
import tornado.httpserver

# XMLRpc imports
import xmlrpclib


# Asynchronous gevent decorator
def gasync(func):
@tornado.web.asynchronous
@functools.wraps(func)
def f(self, *args, **kwargs):
return gevent.spawn(func, self, *args, **kwargs)
return f


# Our XML RPC service
xml_service = xmlrpclib.ServerProxy("http://remote_host/rpc/")


class MyHandler(tornado.web.RequestHandler):
@gasync
def get(self):
# This doesn"t block tornado thanks to gevent
# Which patches all of xmlrpclib"s socket calls
# So they no longer are blocking
result = xml_service.system.listmethods()

# Do something here

# Write response to client
self.write("hello")
self.finish()


# Our URL Mappings
handlers = [
(r"/", MyHandler),
]


def main():
# Setup app and HTTP server
application = tornado.web.Application(handlers)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8000)

# Start ioloop
tornado.ioloop.IOLoop.instance().start()


if __name__ == "__main__":
main()

だから例を試してみて(明らかにあなたのニーズに合わせて)あなたは行ってもいいはずです。

余分なコードを書く必要はありません。geventはpythonソケットにパッチをあてるというすべての作業を行うので、同期的にコードを書いている間も非同期に使用できます(これは本当の利点です)。

お役に立てれば :)


回答№2の場合は0

そうは思わない。 Tornadoにはそれ自身のioloopがありますが、geventのi iroopはlibeventです。 だからgeventはTornadoのioloopをブロックするでしょう。