stabilize app shutdown flow and resource cleanup

This commit is contained in:
Shivering Ocelot committed 2026-06-30 10:59:46 -05:00
1 parent 878a09f9e9
commit 2b44dcebf4
3 files changed
+41 -11

No files matched your search

+27 -7
View File
@@ -4,6 +4,7 @@ import json
import time
import sys
import os
import signal
from tortoise import Tortoise
from tortoise.expressions import Q
@@ -28,6 +29,8 @@ class App(ChatMixin):
self.remote_connections = {}
self.streams = {}
self.event_listeners = []
# active websocket tasks, for manual cancelling upon server shutdown
self.ws_tasks = []
self.tmp = tmp.State()
@@ -380,12 +383,29 @@ async def main():
)
# 3. Start Server
# Note: start_server must be an async function or handle an event loop
await start_server(horde_app)
# manually trigger server shutdown, avoids hypercorn installing signal handlers
shutdown_event = asyncio.Event()
server_task = asyncio.create_task(start_server(horde_app, shutdown_event))
# 4. Graceful Termination
loop = asyncio.get_running_loop()
def interrupt():
print("Interrupt Signal")
shutdown_event.set()
# Unblock websocket handlers parked in websocket.receive()
for task in list(horde_app.ws_tasks):
task.cancel()
for sig in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(sig, interrupt)
try:
await server_task
finally:
print("Server stopped")
horde_app.qdrant_client.close()
await Tortoise.close_connections()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
# Clean shutdown for Tortoise connections
asyncio.run(Tortoise.close_connections())
asyncio.run(main())