2016-07-24 13 views
1

Ich möchte einen Tornado-Server für Test- und Demozwecke stoppen und neu starten können. Aber es scheint den Port nicht freizugeben.Wie kann ich einen Tornado-Server stoppen (und neu starten!)?

Der folgende Code basiert auf answer showing how to properly stop Tornado. Ich habe gerade den Code unten hinzugefügt, der versucht, Tornado neu zu starten. Es schlägt mit der Ausnahme "error: Address in use" fehl. Ich habe sogar einen Anruf zu ioloop.close() hinzugefügt, aber das hat nicht geholfen.

#! /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() 

Ausgang:

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

ich Sie Ihre eigenen Threads in Tornado nicht denken müssen verwalten. Das ioloop macht das für dich, dachte ich –

Antwort

2

Sie Fäden nicht so verwenden, wenn Sie wirklich Notwendigkeit - sie Dinge ziemlich viel komplizierter. Verwenden Sie für Tests tornado.testing.AsyncTestCase oder AsyncHTTPTestCase.

Um den Port freizugeben, müssen Sie die HTTPServer stoppen, nicht nur die IOLoop. In der Tat, Sie müssen nicht einmal die IOLoop überhaupt stoppen. (Aber normalerweise würde ich alles neu starten, indem ich den Prozess einfach beenden und von Grund auf neu starten würde).

würde eine nicht-Thread-Version von Ihrem Beispiel so etwas wie:

#! /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() 
+0

Danke, Ben. Was wird Tornado tun, wenn dir etwas passiert? – JohnMudd