我有两个requesthandler。一个提供大量的auf数据,另一个只提供一些数据集。
class HugeQueryHandler(BaseHandler):
@gen.coroutine
def get(self):
try:
cursor = yield momoko.Op(self.db.execute, 'SELECT * FROM huge_table;')
for row in cursor:
self.write('Query results: {} <br />'.format(row))
except Exception as error:
self.write(str(error))
self.finish()
class SmallQueryHandler(BaseHandler):
@gen.coroutine
def get(self):
try:
cursor = yield momoko.Op(self.db.execute, 'SELECT * FROM small_table;')
for row in cursor:
self.write('Query results: {} <br />'.format(row))
except Exception as error:
self.write(str(error))
self.finish()
我的问题:
响应循环阻塞吗?当我在调用巨大的处理程序后请求少量数据时,我必须等待,第一个完成...
答案 0 :(得分:0)
write()
不会在网络上阻塞(它只是附加到缓冲区),但是你不会放弃任何地方,所以在任何其他任务可以运行之前,整个循环必须运行完成。我认为问题不在于写入,而是迭代 - “for cursor in cursor”不会产生,所以momoko将整个结果集缓存在内存中,或者在从数据库读取时阻塞。如果是后者,则需要以非阻塞方式访问游标。如果是前者,除了将查询分解为更小的块之外,可能没有太多可以解决的问题。 (你可以偶尔在循环中调用“yield gen.Task(self.flush)”,但是这会延长在内存中缓冲全部数量的时间,因此可能不合适。)
答案 1 :(得分:0)
所以,这就是重点。 for循环需要完成。
这种方法是什么?
class HugeQueryHandler(BaseHandler):
executor = tornado.concurrent.futures.ThreadPoolExecutor(1)
@tornado.concurrent.run_on_executor
def generate_response(self, cursor):
return "<br />".join("{}".format(row) for row in cursor)
@tornado.web.asynchronous
@gen.engine
def get(self):
try:
cursor = yield momoko.Op(self.db.execute, 'SELECT * FROM huge_table;')
res = yield self.generate_response(cursor)
self.write(res)
except Exception as error:
self.write(str(error))
self.finish()