tornado 异步得到结果后write报错Cannot write() after finish()

发布于 2022-09-06 02:48:55 字数 2526 浏览 11 评论 0

@tornado.web.authenticated
@tornado.web.asynchronous
@gen.coroutine
def handler(self):
        request = json.loads(self.request.body)
        if not request.get('tenant_id'):
            raise Exception('tenant_id not found')
        tenant_id = request.get('tenant_id')

        big_ins_list =[]
        for fla in flavor_list:
            result= yield tornado.gen.Task(self.fetch_res,tenant_id=tenant_id,flavor_id=fla) 

            big_ins_list.append(result)
        big_ins_list.sort(key=lambda x:x.instances_num,reverse=True)
        #在这里我已经得到了执行的结果
        self.write({
            'data':{
                'company_name':company_name,
                'tenant_id':tenant_id,
                'flavors':[{
                    'instance_type_id':item.instance_type_id,
                    'flavor_name':item.flavor_name,
                    'instances_num':item.instances_num,
                }for item in big_ins_list]
            }
        })
@gen.coroutine
def fetch_res(self,**kwargs):
    '''
    一个耗时的查询库操作,将结果rasie 返回,因为python3.2之前生成器不许return
    '''
    sql = '''
    一个sql
    '''%(int(kwargs['flavor_id']),kwargs['tenant_id'])
    cursor.execute(sql)
    res = cursor.fentchall()
    res_list =一些处理过程    
    raise gen.Return(res_list)
    
    

报错如下:

Traceback (most recent call last):
  File "/krdsdata/virtualenv/lib/python2.6/site-packages/tornado/web.py", line 1425, in _stack_context_handle_exception
    raise_exc_info((type, value, traceback))
  File "/krdsdata/virtualenv/lib/python2.6/site-packages/tornado/stack_context.py", line 314, in wrapped
    ret = fn(*args, **kwargs)
  File "/krdsdata/virtualenv/lib/python2.6/site-packages/tornado/web.py", line 1638, in future_complete
    f.result()
  File "/krdsdata/virtualenv/lib/python2.6/site-packages/tornado/concurrent.py", line 237, in result
    raise_exc_info(self._exc_info)
  File "/krdsdata/virtualenv/lib/python2.6/site-packages/tornado/gen.py", line 1024, in run
    yielded = self.gen.send(value)
  File "/krdsdata/krds-beacon_test/beacon/applacation/handler/handlers.py", line 763, in list_flavor_by_tenant_id
    }for item in big_ins_list]
  File "/krdsdata/virtualenv/lib/python2.6/site-packages/tornado/web.py", line 703, in write
    raise RuntimeError("Cannot write() after finish()")
RuntimeError: Cannot write() after finish()  

按照这种写法这个方法已经是异步非阻塞的了(执行这个方法的时候不会阻塞别的请求),但是最后write到前端的时候,报已经finish了,我看了下源码,再被asynchronous装饰的时候回调用了finish()。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好 2022-09-13 02:48:55

使用了yield tornado.gen.Task 调用协程的方式,就不需要再使用tornado.web.asynchronous了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文