如何停止(并重新启动!)Tornado服务器?

时间:2016-07-24 17:20:14

标签: python python-2.7 tornado

我希望能够停止并重新启动Tornado服务器以进行测试和演示。但它似乎没有释放端口。

以下代码基于answer showing how to properly stop Tornado。我刚刚在底部添加了试图重启Tornado的代码。它失败并显示“错误:正在使用的地址”异常。我甚至添加了对ioloop.close()的电话,但这没有帮助。

#! /usr/bin/env python

import threading
import tornado.ioloop
import tornado.web
import time


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world!\n")

def start_tornado(*args, **kwargs):
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    print "Starting Torando"
    tornado.ioloop.IOLoop.instance().start()
    print "Tornado finished"

def stop_tornado():
    ioloop = tornado.ioloop.IOLoop.instance()
    ioloop.add_callback(ioloop.stop)
    ioloop.add_callback(ioloop.close) # I added this but it didn't help.
    print "Asked Tornado to exit"

def main():

    t = threading.Thread(target=start_tornado)
    t.start()

    time.sleep(1)

    stop_tornado()
    t.join()
    print "Tornado thread stopped."

    t = threading.Thread(target=start_tornado) # Attempt restart.
    t.start()

if __name__ == "__main__":
    main()

输出:

Starting Torando
Asked Tornado to exit
 Tornado finished
Tornado thread stopped.
Exception in thread Thread-2:
    Traceback (most recent call last):
          File "/home/mudd/musl/Python-2.7.11.install/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/home/mudd/musl/Python-2.7.11.install/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "./test_tonado_restart.py", line 17, in start_tornado
    application.listen(8888)
  File "/home/mudd/musl/Python-2.7.11.install/lib/python2.7/site-packages/tornado/web.py", line 1825, in listen
    server.listen(port, address)
  File "/home/mudd/musl/Python-2.7.11.install/lib/python2.7/site-packages/tornado/tcpserver.py", line 126, in listen
    sockets = bind_sockets(port, address=address)
  File "/home/mudd/musl/Python-2.7.11.install/lib/python2.7/site-packages/tornado/netutil.py", line 196, in bind_sockets
    sock.bind(sockaddr)
  File "/home/mudd/musl/Python-2.7.11.install/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 98] Address in use

1 个答案:

答案 0 :(得分:3)

除非真的需要,否则不要使用这样的线程 - 它们会使事情变得复杂。对于测试,请使用tornado.testing.AsyncTestCaseAsyncHTTPTestCase

要释放端口,您需要停止HTTPServer,而不仅仅是IOLoop。实际上,您甚至可能根本不需要停止IOLoop。 (但通常我只需让进程退出并从头开始重新启动即可重新启动所有内容。)

您的示例的非线程版本将类似于:

#! /usr/bin/env python

import tornado.ioloop
import tornado.web
import time


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world!\n")

def start_app(*args, **kwargs):
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    server = application.listen(8888)
    print "Starting app"
    return server

def stop_tornado():
    ioloop = tornado.ioloop.IOLoop.current()
    ioloop.add_callback(ioloop.stop)
    print "Asked Tornado to exit"

def main():
    server = start_app()
    tornado.ioloop.IOLoop.current().add_timeout(
        datetime.timedelta(seconds=1),
        stop_tornado)
    tornado.ioloop.IOLoop.current().start()
    print "Tornado finished"
    server.stop()

    # Starting over
    start_app()
    tornado.ioloop.IOLoop.current().start()