我想实现一个基于tornado 的web 服务,它可以为用户提供数据库查询服务。我使用 pyodbc 模块连接到数据库并进行查询。在实践中,我发现打印查询结果需要很长时间。也就是说,如果我用下面的代码打印查询结果
while 1:
data = cursor.fetchone()
if not data: break
self.write(data + '\n')
self.flush()
sql命令类似于
select * from <a large dummy table>
在循环结束之前,tornado 不会打印查询结果。而且需要很长时间。
我想利用 tornado 的非阻塞异步特性让其他用户也可以使用 web 服务,即使打印当前用户的查询请求的循环还没有完成。
所以我写了类似的东西:
@tornado.web.asynchronous
def get(self):
try:
cnxn = pyodbc.connect(self.server, self.driver, self.table, self.uid, self.pwd)
except Exception, e:
print e
return
try:
self.cur = cnxn.execute(self.sql)
except Exception, e:
print e
return
self.wait_for_query(callback=self.async_callback(self.on_finish))
def wait_for_query(self, callback):
while 1:
data = self.cur.fetchone()
if not data: break
self.write(data)
self.flush()
callback()
def on_finish(self):
self.finish()
我读了这篇文章: Asynchronous COMET query with Tornado and Prototype ,我知道我的解决方案行不通。但我当然不能使用 add_timeout,因为我无法弄清楚迭代会持续多长时间。那么我怎样才能通过这个来实现我的目标呢?