Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Created January 21, 2025 16:29
Show Gist options
  • Save mrexodia/26c17b6c9785a75fc2028dd3b775a722 to your computer and use it in GitHub Desktop.
Save mrexodia/26c17b6c9785a75fc2028dd3b775a722 to your computer and use it in GitHub Desktop.
Tornado graceful shutdown from a thread
import threading
import tornado.ioloop
import tornado.web
import time
import asyncio
import logging
import requests
g_ioloop = None
g_server = None
class MainHandler(tornado.web.RequestHandler):
def get(self):
current = tornado.ioloop.IOLoop.current()
print(f"[tornado] current(): {current}")
self.write("Hello, world!\n")
def start_tornado(*args, **kwargs):
# Create a new event loop for the thread
# https://github.com/tornadoweb/tornado/issues/2308#issuecomment-372582005
loop = asyncio.new_event_loop()
loop.set_debug(False)
loop._MY_THREAD = True
logging.getLogger("asyncio").setLevel(logging.CRITICAL) # Remove some debug spam
asyncio.set_event_loop(loop)
print(f"thread loop: {loop}")
global g_ioloop, g_server
application = tornado.web.Application([
(r"/", MainHandler),
])
g_server = application.listen(8888)
print("Starting Torando")
g_ioloop = tornado.ioloop.IOLoop.current()
g_ioloop.start()
print("Tornado finished")
def stop_tornado():
global g_ioloop
current = tornado.ioloop.IOLoop.current()
print(f"[tornado] g_ioloop: {g_ioloop}\n[main] current(): {current}")
g_ioloop.add_callback(g_server.stop)
g_ioloop.add_callback(g_server.close_all_connections)
g_ioloop.add_callback(g_ioloop.stop)
print("Asked Tornado to exit")
def main():
"""
# Create a new event loop for the main thread (not necessary)
# https://github.com/tornadoweb/tornado/issues/2308#issuecomment-372582005
loop = asyncio.new_event_loop()
loop.set_debug(False)
loop._MY_MAIN = True
logging.getLogger("asyncio").setLevel(logging.CRITICAL) # Remove some debug spam
asyncio.set_event_loop(loop)
"""
asyncio.get_event_loop()._MY_MAIN = True
current = tornado.ioloop.IOLoop.current()
print(f"[main] current(): {current}")
t = threading.Thread(target=start_tornado)
t.start()
time.sleep(0.2)
r = requests.get("http://localhost:8888")
print(r.text)
time.sleep(1)
stop_tornado()
t.join()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment