8

我正在尝试在 Tornado 的 RequestHandler 中实现 get_current_user,但是在等待对我的数据库的异步调用时,我需要阻塞调用。使用 @tornado.web.asynchronous 装饰调用将不起作用,因为无论哪种方式 get_current_user 方法在异步查询完成和查询回调执行之前返回。

例如:

class MyHandler(BaseHandler):
  @tornado.web.asynchronous
  @tornado.web.authenticated
  def get(self):
    self.write('example')
    self.finish()

class BaseHandler(tornado.web.RequestHandler):
  def get_current_user(self):
    def query_cb(self, doc):
      return doc or None

    database.get(username='test', password='t3st', callback=query_cb)

@tornado.web.authenticated 调用 get_current_user,但总是收到“None”,因为 BaseHandler 没有时间响应。有没有办法,使用龙卷风,暂时阻止一个电话,如上面的电话?

4

3 回答 3

4

执行阻塞数据库操作而不是上述非阻塞操作(tornado 附带了一个阻塞 mysql 库)。

来自 Tornado wiki 关于线程和并发的页面:“同步执行并阻止 IOLoop。这最适合您控制的内存缓存和数据库查询之类的事情,并且应该始终快速。如果速度不快,请通过将适当的索引添加到数据库等"

https://github.com/facebook/tornado/wiki/Threading-and-concurrency

于 2011-02-08T22:18:15.330 回答
2

get_current_user当返回来自数据库的异步响应时,返回一个Future您发出的信号怎么样?

class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        future = Future()
        def query_cb(user):
            future.set_result(user or None)
        database.get(username='test', password='t3st', callback=query_cb)
        return future


class MainHandler(BaseHandler):
    @gen.coroutine
    def get(self):
        user = yield self.get_current_user()
        self.write('user: ' + user)
        # ... actual request processing
于 2017-09-01T23:12:27.793 回答
0

我认为 Tornado 允许您发出阻塞或非阻塞请求。

这是两者都使用的 Tornado:https ://bitbucket.org/nephics/tornado-couchdb/src/147579581b47/couch.py

免责声明:我对 Python 和 Tornado 知之甚少。

于 2011-07-19T14:50:03.927 回答