stabilize app shutdown flow and resource cleanup
This commit is contained in:
1 parent
878a09f9e9
commit
2b44dcebf4
3 files changed
+41
-11
No files matched your search
+27
-7
@@ -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())
|
||||
Reference in new issue
Block a user