2

基本的に、次の方法で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)ますか?
4

2 に答える 2

3

1.はい、xmlrpclibはブロッキングpythonソケットを使用するため、トルネードをブロックします(そのまま)

2.私が知っていることではありませんが、xmlrpclibを維持しながら非同期にすることができるソリューションを提供します

3.私のソリューションはtornadogenを使用していません。

さて、ネットワーキングを行っていて非同期コードを書く必要があるときに覚えておくと便利なライブラリの1つはgeventです。これは、私がすべての人に推奨する非常に優れた高品質のライブラリです。

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

  • 非同期コードを同期的に書くことができます(それで簡単になります)
  • あなたがしなければならないのは、そうするために、1つの単純な行を持つモンキーパッチです:

    geventインポートモンキーから; Monkey.patch_all()

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

  • Tornadoは、HTTPServerとして機能する場合にのみ非同期ビューをサポートします(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ソケットにパッチを適用するすべての作業を行うため、同期方式でコードを記述しながら非同期で使用できます(これは本当のボーナスです)。

お役に立てれば :)

于 2012-11-11T01:04:02.370 に答える
0

そうは思わない。Tornadoには独自のioloopがありますが、geventのioloopはlibeventです。したがって、geventはトルネードのioloopをブロックします。

于 2013-09-24T09:13:19.190 に答える