我希望能够停止并重新启动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
答案 0 :(得分:3)
除非真的需要,否则不要使用这样的线程 - 它们会使事情变得复杂。对于测试,请使用tornado.testing.AsyncTestCase
或AsyncHTTPTestCase
。
要释放端口,您需要停止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()