Cron cleanup
This commit is contained in:
parent
8ac523bc26
commit
7556176229
2 changed files with 53 additions and 1 deletions
|
@ -34,6 +34,7 @@ class AsyncServer:
|
||||||
def enter_room(self, sid: str, room: str) -> None: ...
|
def enter_room(self, sid: str, room: str) -> None: ...
|
||||||
def leave_room(self, sid: str, room: str) -> None: ...
|
def leave_room(self, sid: str, room: str) -> None: ...
|
||||||
def attach(self, app: Any) -> None: ...
|
def attach(self, app: Any) -> None: ...
|
||||||
|
async def disconnect(self, sid: str) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class AsyncClient:
|
class AsyncClient:
|
||||||
|
|
|
@ -20,7 +20,9 @@ import random
|
||||||
import string
|
import string
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from dataclasses import field
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from typing import AsyncGenerator
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import socketio
|
import socketio
|
||||||
|
@ -56,7 +58,7 @@ async def root_handler(request: Any) -> Any:
|
||||||
return web.FileResponse("syng/static/index.html")
|
return web.FileResponse("syng/static/index.html")
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,6 +114,9 @@ class State:
|
||||||
recent: list[Entry]
|
recent: list[Entry]
|
||||||
sid: str
|
sid: str
|
||||||
config: Config
|
config: Config
|
||||||
|
last_seen: datetime.datetime = field(
|
||||||
|
init=False, default_factory=datetime.datetime.now
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
clients: dict[str, State] = {}
|
clients: dict[str, State] = {}
|
||||||
|
@ -325,6 +330,7 @@ async def handle_pop_then_get_next(sid: str) -> None:
|
||||||
|
|
||||||
old_entry = await state.queue.popleft()
|
old_entry = await state.queue.popleft()
|
||||||
state.recent.append(old_entry)
|
state.recent.append(old_entry)
|
||||||
|
state.last_seen = datetime.datetime.now()
|
||||||
|
|
||||||
await send_state(state, room)
|
await send_state(state, room)
|
||||||
current = await state.queue.peek()
|
current = await state.queue.peek()
|
||||||
|
@ -715,6 +721,49 @@ async def handle_search(sid: str, data: dict[str, Any]) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def cleanup() -> None:
|
||||||
|
""" Clean up the unused playback clients
|
||||||
|
|
||||||
|
This runs every hour, and removes every client, that did not requested a song for four hours
|
||||||
|
"""
|
||||||
|
|
||||||
|
logger.info("Start Cleanup")
|
||||||
|
to_remove: list[str] = []
|
||||||
|
for sid, state in clients.items():
|
||||||
|
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]
|
||||||
|
logger.info("End Cleanup")
|
||||||
|
|
||||||
|
|
||||||
|
# The internal loop counter does not use a regular timestamp, so we need to convert between
|
||||||
|
# regular datetime and the async loop time
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
today = datetime.datetime(now.year, now.month, now.day)
|
||||||
|
next_run = today + datetime.timedelta(days=1)
|
||||||
|
offset = next_run.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()))
|
||||||
|
|
||||||
|
async def background_tasks(iapp: web.Application) -> AsyncGenerator[None, None]:
|
||||||
|
""" Create all the background tasks
|
||||||
|
|
||||||
|
For now, this is only the cleanup task
|
||||||
|
"""
|
||||||
|
|
||||||
|
iapp["repeated_cleanup"] = asyncio.create_task(cleanup())
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
iapp["repeated_cleanup"].cancel()
|
||||||
|
await iapp["repeated_cleanup"]
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
"""
|
"""
|
||||||
Configure and start the server.
|
Configure and start the server.
|
||||||
|
@ -734,6 +783,8 @@ def main() -> None:
|
||||||
app.router.add_route("*", "/{room}", root_handler)
|
app.router.add_route("*", "/{room}", root_handler)
|
||||||
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)
|
web.run_app(app, host=args.host, port=args.port)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue