From bc1afc5aa0cc1ccf5389a1fb31891c8af47a716a Mon Sep 17 00:00:00 2001
From: Christoph Stahl <christoph.stahl@tu-dortmund.de>
Date: Wed, 25 Jan 2023 16:07:07 +0100
Subject: [PATCH] Initial work for clean up done

---
 syng/server.py | 44 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 37 insertions(+), 7 deletions(-)

diff --git a/syng/server.py b/syng/server.py
index b3fd9ae..1ec2852 100644
--- a/syng/server.py
+++ b/syng/server.py
@@ -58,7 +58,7 @@ async def root_handler(request: Any) -> Any:
     return web.FileResponse("syng/static/index.html")
 
 
-logging.basicConfig(level=logging.INFO)
+logging.basicConfig(level=logging.WARNING)
 logger = logging.getLogger(__name__)
 
 
@@ -114,7 +114,9 @@ class State:
     recent: list[Entry]
     sid: str
     config: Config
-    last_seen: datetime.datetime = field(init=False, default_factory=datetime.datetime.now)
+    last_seen: datetime.datetime = field(
+        init=False, default_factory=datetime.datetime.now
+    )
 
 
 clients: dict[str, State] = {}
@@ -326,7 +328,7 @@ async def handle_pop_then_get_next(sid: str) -> None:
     if sid != state.sid:
         return
 
-    old_entry = await state.queue.popleft()    
+    old_entry = await state.queue.popleft()
     state.recent.append(old_entry)
     state.last_seen = datetime.datetime.now()
 
@@ -718,12 +720,38 @@ async def handle_search(sid: str, data: dict[str, Any]) -> None:
         room=sid,
     )
 
-@aiocron.crontab('* * * * *')
-async def cleanup():
+
+async def cleanup(app):
     logger.info("Start Cleanup")
+    to_remove = []
     for sid, state in clients.items():
-        logger.info("Client %d, last seen: %s", sid, str(state.last_seen))
-        
+        logger.info("Client %s, last seen: %s", sid, str(state.last_seen))
+        if state.last_seen + datetime.timedelta(hours=4) < datetime.datetime.now():
+            logger.info("No activity for 4 hours, removing %s", sid)
+            to_remove.append(sid)
+    for sid in to_remove:
+        await sio.disconnect(sid)
+        del clients[sid]
+
+
+    now = datetime.datetime.now()
+    today = datetime.datetime(now.year, now.month, now.day)
+    next = today + datetime.timedelta(days=1)
+    # next = now + datetime.timedelta(seconds=2)
+    offset = next.timestamp() - now.timestamp()
+    loop_next = asyncio.get_event_loop().time() + offset
+
+    logger.info("Next Cleanup at %s", str(next))
+    asyncio.get_event_loop().call_at(loop_next, lambda: asyncio.create_task(cleanup(app)))
+
+async def background_tasks(app):
+    app["cron_cleanup"] = asyncio.create_task(cleanup(app))
+
+    yield
+
+    app["cron_cleanup"].cancel()
+    await app["cron_cleanup"]
+
 def main() -> None:
     """
     Configure and start the server.
@@ -743,6 +771,8 @@ def main() -> None:
     app.router.add_route("*", "/{room}", root_handler)
     app.router.add_route("*", "/{room}/", root_handler)
 
+    app.cleanup_ctx.append(background_tasks)
+
     web.run_app(app, host=args.host, port=args.port)
 
 
-- 
GitLab