diff --git a/src/myfasthtml/auth/routes.py b/src/myfasthtml/auth/routes.py index 9c99494..26a4cc6 100644 --- a/src/myfasthtml/auth/routes.py +++ b/src/myfasthtml/auth/routes.py @@ -16,6 +16,7 @@ from ..auth.utils import ( logout_user, get_user_info ) +from ..core.instances import InstancesManager def setup_auth_routes(app, rt, mount_auth_app=True, sqlite_db_path="Users.db", base_url=None): @@ -181,6 +182,9 @@ def setup_auth_routes(app, rt, mount_auth_app=True, sqlite_db_path="Users.db", b if refresh_token: logout_user(refresh_token) + # release memory + InstancesManager.clear_session(session) + # Clear session session.clear() diff --git a/src/myfasthtml/controls/InstancesDebugger.py b/src/myfasthtml/controls/InstancesDebugger.py index 5c9d8c7..7428b0d 100644 --- a/src/myfasthtml/controls/InstancesDebugger.py +++ b/src/myfasthtml/controls/InstancesDebugger.py @@ -8,12 +8,13 @@ class InstancesDebugger(SingleInstance): super().__init__(parent, _id=_id) def render(self): + s_name = InstancesManager.get_session_user_name instances = self._get_instances() nodes, edges = from_parent_child_list( instances, - id_getter=lambda x: f"{InstancesManager.get_session_id(x.get_session())}-{x.get_id()}", - label_getter=lambda x: x.get_prefix(), - parent_getter=lambda x: x.get_parent().get_id() if x.get_parent() else None + id_getter=lambda x: x.get_full_id(), + label_getter=lambda x: f"{s_name(x.get_session())}-{x.get_prefix()}", + parent_getter=lambda x: x.get_full_parent_id() ) for edge in edges: edge["color"] = "green" diff --git a/src/myfasthtml/core/instances.py b/src/myfasthtml/core/instances.py index 7bab51f..cd74baa 100644 --- a/src/myfasthtml/core/instances.py +++ b/src/myfasthtml/core/instances.py @@ -86,6 +86,13 @@ class BaseInstance: def get_prefix(self) -> str: return self._prefix + def get_full_id(self) -> str: + return f"{InstancesManager.get_session_id(self._session)}-{self._id}" + + def get_full_parent_id(self) -> Optional[str]: + parent = self.get_parent() + return parent.get_full_id() if parent else None + @classmethod def compute_prefix(cls): return f"mf-{pascal_to_snake(cls.__name__)}" @@ -177,10 +184,33 @@ class InstancesManager: return "** UNKNOWN USER **" return session["user_info"].get("id", "** INVALID SESSION **") + @staticmethod + def get_session_user_name(session): + if session is None: + return "** NOT LOGGED IN **" + if "user_info" not in session: + return "** UNKNOWN USER **" + return session["user_info"].get("username", "** INVALID SESSION **") + @staticmethod def reset(): InstancesManager.instances.clear() + @staticmethod + def clear_session(session): + """ + Remove all instances belonging to the given session. + :param session: + :return: + """ + session_id = InstancesManager.get_session_id(session) + + InstancesManager.instances = { + key: instance + for key, instance in InstancesManager.instances.items() + if key[0] != session_id + } + @staticmethod def dynamic_get(parent: BaseInstance, component_type: str, instance_id: str): logger.debug(f"Dynamic get: {component_type=} {instance_id=}") diff --git a/src/myfasthtml/core/network_utils.py b/src/myfasthtml/core/network_utils.py index 0d2074a..bb23880 100644 --- a/src/myfasthtml/core/network_utils.py +++ b/src/myfasthtml/core/network_utils.py @@ -147,7 +147,7 @@ def from_parent_child_list( id_getter: Callable = None, label_getter: Callable = None, parent_getter: Callable = None, - ghost_color: str = "#ff9999", + ghost_color: str = "#cccccc", root_color: str | None = "#ff9999" ) -> tuple[list, list]: """