龙卷风提出的例外

时间:2016-02-29 12:30:29

标签: python tornado

我用Tornado写了一个简单的http服务器,但有时会引发下面的异常,self.session.response在一个线程池中运行。

服务器代码:

class AuToServer(object):

    module_path = os.path.split(os.path.realpath(__file__))[0] + '/../module/'

    def __init__(self, prefix=DEFAULT_PREFIX, work_root=module_path, module=[], **kwargs):
        self._prefix = prefix
        self._thread_pool = ExecutorDelegate(20)
        self._module_manager = ModuleManager(work_root)
        self.initilize(module, kwargs)

    def initilize(self, modules, kwargs):

        self._module_manager.set_args(kwargs)
        if not self._module_manager.prepare(modules):
            print "initilize module fail. [%s]" % (str(modules))
            raise AppInitError("initilize %s fail" % (modules))

    def __call__(self, request):                # request handler
        session = Session(request) 

        if not session.parse(self._prefix):
            print "parse query fail. [%s]" % (session.query)
            session.response("url parse fail [%s]\n" % session.query)
            return

        self._thread_pool.submit(WorkerHander(self._module_manager, session))

    def start(self, port=8880):
        http_server = tornado.httpserver.HTTPServer(self, max_header_size=128*1024)
        http_server.listen(port)
        tornado.ioloop.IOLoop.instance().start()

代码WorkerHander

class WorkerHander(BaseExecutor):

    def __init__(self, module_manage, session):
        self.module_manage = module_manage
        self.session = session
        super(WorkerHander, self).__init__(self)

    def run(self):
        method = self.session.get_command()
        if not method:
            self.session.response("invalid url [%s]\n" % (self.session.query))
            return

        context = self.module_manage.run(method, self.session)
        try:
            if context:
                self.session.response(context)    # raise exception
            else:
                self.session.response("None\n")
        except Exception, error:
            Logger.warning("session response fail. [%s][%s]" % (self.session.query, traceback.format_exc()))

代码session.response

def response(self, context):
    if not self.request:
        return False 

    if isinstance(context, unicode):
        context = context.encode("utf8")
    self.request.write(utf8("%s %d\r\n\r\n%s" % ( 
                        HTTP_HEADER,
                        len(context), 
                        context)))
    Logger.debug("QUERY:[cmd:%s][%s] [%s] [%s]" % ( 
                  self.command,
                  time.time() - self.begin_time, 
                  self.request.remote_ip,
                  self.query))

    self.request.finish()
    return True

异常:

2016-02-29 16:29:26,852 WARNING: server.py:run:94: session response fail. [/auto?start_timestamp=1456730772&_cmd=get_index_info][Traceback (most recent call last):
  File "/home/admin/autobots/lib/python2.7/site-packages/autobase-0.0.1-py2.7.egg/autobase/service/server.py", line 90, in run
    self.session.response(context)
  File "/home/admin/autobots/lib/python2.7/site-packages/autobase-0.0.1-py2.7.egg/autobase/service/session.py", line 43, in response
    self.request.finish()
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/httputil.py", line 407, in finish
    self.connection.finish()
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/http1connection.py", line 459, in finish
    self._pending_write.add_done_callback(self._finish_request)
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/concurrent.py", line 243, in add_done_callback
    fn(self)
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/http1connection.py", line 491, in _finish_request
    self.close()
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/http1connection.py", line 297, in close
    self.stream.close()
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/iostream.py", line 427, in close
    self.close_fd()
  File "/home/admin/autobots/lib/python2.7/site-packages/tornado-4.2-py2.7-linux-x86_64.egg/tornado/iostream.py", line 995, in close_fd
    self.socket.close()
AttributeError: 'NoneType' object has no attribute 'close'
]

我是否以错误的方式使用龙卷风?请求帮忙。感谢〜

1 个答案:

答案 0 :(得分:2)

龙卷风的设计是not thread-safe。您可以使用线程池来完成自己的工作,但必须从self.request.write线程调用所有Tornado方法(在本例中包括self.request.finishIOLoop)。