Fix memory leaked caused by RefreshService #65

Merged
Typhus merged 1 commits from bugfix/fix-memory-leak into main 2026-04-17 07:34:16 +00:00
7 changed files with 30 additions and 24 deletions
Showing only changes of commit c349fe475b - Show all commits

View File

@ -1 +1 @@
0.3.7 0.3.8

View File

@ -3,15 +3,13 @@ import logging
import sys import sys
from pathlib import Path from pathlib import Path
from uuid import uuid4
from rio import App, Theme, Color, Font, ComponentPage, Session from rio import App, Theme, Color, Font, ComponentPage, Session
from from_root import from_root from from_root import from_root
from src.ezgg_lan_manager import pages, init_services, LocalDataService from src.ezgg_lan_manager import pages, init_services, LocalDataService, RefreshService
from src.ezgg_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard, team_guard from src.ezgg_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard, team_guard
from src.ezgg_lan_manager.services.LocalDataService import LocalData from src.ezgg_lan_manager.services.LocalDataService import LocalData
from src.ezgg_lan_manager.types.UserSession import UserSession
logger = logging.getLogger("EzggLanManager") logger = logging.getLogger("EzggLanManager")
@ -38,6 +36,7 @@ if __name__ == "__main__":
# Use this line to fake being any user without having to log in # Use this line to fake being any user without having to log in
# session.attach(UserSession(id=uuid4(), user_id=30, is_team_member=True)) # session.attach(UserSession(id=uuid4(), user_id=30, is_team_member=True))
await session.set_title(lan_info.name) await session.set_title(lan_info.name)
session.attach(RefreshService())
if session[LocalData].stored_session_token: if session[LocalData].stored_session_token:
user_session = session[LocalDataService].verify_token(session[LocalData].stored_session_token) user_session = session[LocalDataService].verify_token(session[LocalData].stored_session_token)
if user_session is not None: if user_session is not None:
@ -216,7 +215,14 @@ if __name__ == "__main__":
} }
) )
sys.exit(app.run_as_web_server( try:
app.run_as_web_server(
host="0.0.0.0", host="0.0.0.0",
port=8000, port=8000,
)) )
except (KeyboardInterrupt, SystemExit):
logger.info("EZGG LAN Manager was shut down.")
sys.exit(0)
except Exception as e:
logger.error(e)
sys.exit(1)

View File

@ -20,7 +20,7 @@ from src.ezgg_lan_manager.services.UserService import UserService
from src.ezgg_lan_manager.types import * from src.ezgg_lan_manager.types import *
# Inits services in the correct order # Inits services in the correct order
def init_services() -> tuple[AccountingService, CateringService, ConfigurationService, DatabaseService, MailingService, NewsService, SeatingService, TicketingService, UserService, LocalDataService, ReceiptPrintingService, TournamentService, TeamService, RefreshService]: def init_services() -> tuple[AccountingService, CateringService, ConfigurationService, DatabaseService, MailingService, NewsService, SeatingService, TicketingService, UserService, LocalDataService, ReceiptPrintingService, TournamentService, TeamService]:
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
configuration_service = ConfigurationService(from_root("config.toml")) configuration_service = ConfigurationService(from_root("config.toml"))
db_service = DatabaseService(configuration_service.get_database_configuration()) db_service = DatabaseService(configuration_service.get_database_configuration())
@ -37,4 +37,4 @@ def init_services() -> tuple[AccountingService, CateringService, ConfigurationSe
team_service = TeamService(db_service) team_service = TeamService(db_service)
refresh_service = RefreshService() refresh_service = RefreshService()
return accounting_service, catering_service, configuration_service, db_service, mailing_service, news_service, seating_service, ticketing_service, user_service, local_data_service, receipt_printing_service, tournament_service, team_service, refresh_service return accounting_service, catering_service, configuration_service, db_service, mailing_service, news_service, seating_service, ticketing_service, user_service, local_data_service, receipt_printing_service, tournament_service, team_service

View File

@ -68,6 +68,7 @@ class UserInfoBox(Component):
@event.on_populate @event.on_populate
async def async_init(self) -> None: async def async_init(self) -> None:
self.user = await self.session[UserService].get_user(self.user_id) self.user = await self.session[UserService].get_user(self.user_id)
if self.user is not None:
self.user_balance = await self.session[AccountingService].get_balance(self.user.user_id) self.user_balance = await self.session[AccountingService].get_balance(self.user.user_id)
self.user_ticket = await self.session[TicketingService].get_user_ticket(self.user.user_id) self.user_ticket = await self.session[TicketingService].get_user_ticket(self.user.user_id)
self.user_seat = await self.session[SeatingService].get_user_seat(self.user.user_id) self.user_seat = await self.session[SeatingService].get_user_seat(self.user.user_id)

View File

@ -18,7 +18,6 @@ class CateringPage(Component):
@event.on_populate @event.on_populate
async def on_populate(self) -> None: async def on_populate(self) -> None:
self.session[RefreshService].subscribe(self.on_populate)
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Catering") await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Catering")
self.all_menu_items = await self.session[CateringService].get_menu() self.all_menu_items = await self.session[CateringService].get_menu()

View File

@ -1,17 +1,17 @@
from typing import Callable from typing import Callable, Optional
class RefreshService: class RefreshService:
""" """
rio.Components can subscribe to this service with their on_populate method. The active rio.Components can subscribe to this service with their on_populate method.
Those methods get called whenever a overall refresh is needed. Usually when the user logs in or out. This methods get called whenever a overall refresh is needed. Usually when the user logs in or out.
""" """
def __init__(self) -> None: def __init__(self) -> None:
self.subscribers: set[Callable] = set() self.subscriber: Optional[Callable] = None
def subscribe(self, refresh_cb: Callable) -> None: def subscribe(self, refresh_cb: Callable) -> None:
self.subscribers.add(refresh_cb) self.subscriber = refresh_cb
async def trigger_refresh(self) -> None: async def trigger_refresh(self) -> None:
for refresh_cb in self.subscribers: if self.subscriber is not None:
await refresh_cb() await self.subscriber()

View File

@ -1,9 +1,9 @@
from dataclasses import dataclass
from uuid import UUID from uuid import UUID
from rio import Dataclass
@dataclass
class UserSession: class UserSession(Dataclass):
id: UUID id: UUID
user_id: int user_id: int
is_team_member: bool is_team_member: bool