Created
January 21, 2025 16:29
-
-
Save mrexodia/26c17b6c9785a75fc2028dd3b775a722 to your computer and use it in GitHub Desktop.
Tornado graceful shutdown from a thread
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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