Jonathan Musther
Jonathan Musther

Reputation: 41

Stopping tornado from thread

I'm running tornado, and monitoring various data sources etc from a separate thread. It's important in this instance to close the web server if the user closes the browser. I'm simply relying on heartbeat requests from the browser, and then want to stop the tornado ioloop. This is proving very difficult:

# Start the main processing loop
mLoop = threading.Thread(target = mainLoop, args=())
mLoop.start()

# Set up webserver
parser = argparse.ArgumentParser(description="Starts a webserver.")
parser.add_argument("--port", type=int, default=8000, help="The port")
args = parser.parse_args()

handlers = [(r"/", IndexHandler), (r"/websocket", WebSocket),
            (r'/static/(.*)', tornado.web.StaticFileHandler,
             {'path': os.path.normpath(os.path.dirname(__file__))})]
application = tornado.web.Application(handlers)
application.listen(args.port)

webbrowser.open("http://localhost:%d/" % args.port, new=2)

tornado.ioloop.IOLoop.instance().start()

The main loop needs to, in certain conditions, stop tornado, but it can't access the ioloop to call IOLoop.stop() (or probably better IOLoop.instance.stop()) because it's not the thread which started it.

What's the best way to accomplish this?

Upvotes: 3

Views: 1737

Answers (1)

sebix
sebix

Reputation: 3239

application.listen returns an HTTPServer instance which you can stop, closing the socket/port. Then close the IOLoop instance.

from tornado.web import Application
from tornado.ioloop import IOLoop

# starting
application = Application(...)
server = application.listen(args.port)
# depends on your use-case
eventLoopThread = Thread(target=IOLoop.current().start)
eventLoopThread.daemon = True
eventLoopThread.start()

# stopping
server.stop()
IOLoop.current().stop()

Upvotes: 3

Related Questions