How do I stop Tornado web server?
Question: I've been playing around a bit with the [Tornado web
server](http://www.tornadoweb.org/) and have come to a point where I want to
stop the web server (for example during unit testing). The following simple
example [exists on the Tornado web
page](http://www.tornadoweb.org/documentation#overview):

    
    
    import tornado.ioloop
    import tornado.web
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
    
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    

Once `tornado.ioloop.IOLoop.instance().start()` is called, it blocks the
program (or current thread). Reading the [source
code](https://github.com/facebook/tornado/blob/master/tornado/ioloop.py#L288)
for the `IOLoop` object gives this example in the documentation for the `stop`
function:

    
    
    To use asynchronous methods from otherwise-synchronous code (such as
    unit tests), you can start and stop the event loop like this:
      ioloop = IOLoop()
      async_method(ioloop=ioloop, callback=ioloop.stop)
      ioloop.start()
    ioloop.start() will return after async_method has run its callback,
    whether that callback was invoked before or after ioloop.start.
    

However, I have no idea how to integrate this into my program. I actually have
a class that encapsulates the web server (having it's own `start` and `stop`
functions), but as soon as I call start, the program (or tests) will of course
block anyway.

I've tried to start the web server in another process (using the
`multiprocessing` package). This is the class that is wrapping the web server:

    
    
    class Server:
        def __init__(self, port=8888):
            self.application = tornado.web.Application([ (r"/", Handler) ])
    
            def server_thread(application, port):
                http_server = tornado.httpserver.HTTPServer(application)
                http_server.listen(port)
                tornado.ioloop.IOLoop.instance().start()
    
            self.process = Process(target=server_thread,
                                   args=(self.application, port,))
    
        def start(self):
            self.process.start()
    
        def stop(self):
            ioloop = tornado.ioloop.IOLoop.instance()
            ioloop.add_callback(ioloop.stop)
    

However, stop does not seem to entirely stop the web server since it is still
running in the next test, even with this test setup:

    
    
    def setup_method(self, _function):
        self.server = Server()
        self.server.start()
        time.sleep(0.5)  # Wait for web server to start
    
    def teardown_method(self, _function):
        self.kstore.stop()
        time.sleep(0.5)
    

How can I start and stop a Tornado web server from within a Python program?


Answer: I just ran into this and found this issue myself, and using info from this
thread came up with the following. I simply took my working stand alone
Tornado code (copied from all the examples) and moved the actual starting code
into a function. I then called the function as a threading thread. My case
different as the threading call was done from my existing code where I just
imported the startTornado and stopTornado routines.

The suggestion above seemed to work great, so I figured I would supply the
missing example code. I tested this code under Linux on a FC16 system (and
fixed my initial type-o).

    
    
    import tornado.ioloop, tornado.web
    
    class Handler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
    
    application = tornado.web.Application([ (r"/", Handler) ])
    
    def startTornado():
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    
    def stopTornado():
        tornado.ioloop.IOLoop.instance().stop()
    
    if __name__ == "__main__":
        import time, threading
        threading.Thread(target=startTornado).start()
        print "Your web server will self destruct in 2 minutes"
        time.sleep(120)
        stopTornado()
    

Hope this helps the next person.

