Improve session storage lifecycle

This commit is contained in:
Lonami Exo 2024-03-01 21:49:44 +01:00
parent 72e6229cc7
commit 2f4065c958
7 changed files with 38 additions and 15 deletions

View File

@ -260,4 +260,9 @@ async def check_password(
async def sign_out(self: Client) -> None: async def sign_out(self: Client) -> None:
await self(functions.auth.log_out()) await self(functions.auth.log_out())
await self._storage.delete() self._chat_hashes.clear()
self._message_box.reset()
self._session.user = None
self._session.state = None
await self._storage.save(self._session)

View File

@ -230,8 +230,13 @@ async def disconnect(self: Client) -> None:
"unhandled exception during disconnect; this is a bug" "unhandled exception during disconnect; this is a bug"
) )
self._session.state = self._message_box.session_state() try:
await self._storage.save(self._session) if self._session.user:
# Only save if we haven't logged out (prevents double-save)
self._session.state = self._message_box.session_state()
await self._storage.save(self._session)
finally:
await self._storage.close()
async def invoke_request( async def invoke_request(

View File

@ -33,6 +33,11 @@ class ChatHashCache:
else: else:
return None return None
def clear(self) -> None:
self._hash_map.clear()
self._self_id = None
self._self_bot = False
def _has(self, id: int) -> bool: def _has(self, id: int) -> bool:
return id in self._hash_map return id in self._hash_map

View File

@ -103,6 +103,14 @@ class MessageBox:
self.getting_diff_for.clear() self.getting_diff_for.clear()
self.next_deadline = ENTRY_ACCOUNT self.next_deadline = ENTRY_ACCOUNT
def reset(self) -> None:
self.map.clear()
self.date = epoch()
self.seq = NO_SEQ
self.possible_gaps.clear()
self.getting_diff_for.clear()
self.next_deadline = None
def session_state(self) -> UpdateState: def session_state(self) -> UpdateState:
return UpdateState( return UpdateState(
pts=self.map[ENTRY_ACCOUNT].pts if ENTRY_ACCOUNT in self.map else NO_PTS, pts=self.map[ENTRY_ACCOUNT].pts if ENTRY_ACCOUNT in self.map else NO_PTS,

View File

@ -24,5 +24,5 @@ class MemorySession(Storage):
async def save(self, session: Session) -> None: async def save(self, session: Session) -> None:
self.session = session self.session = session
async def delete(self) -> None: async def close(self) -> None:
self.session = None pass

View File

@ -52,14 +52,11 @@ class SqliteSession(Storage):
conn = self._current_conn() conn = self._current_conn()
with conn: with conn:
self._save_v10(conn.cursor(), session) self._save_v10(conn.cursor(), session)
conn.close()
self._conn = None
async def delete(self) -> None: async def close(self) -> None:
if self._conn: if self._conn:
self._conn.close() self._conn.close()
self._conn = None self._conn = None
self._path.unlink()
def _current_conn(self) -> sqlite3.Connection: def _current_conn(self) -> sqlite3.Connection:
if self._conn is None: if self._conn is None:

View File

@ -14,7 +14,7 @@ class Storage(abc.ABC):
""" """
Load the :class:`Session` instance, if any. Load the :class:`Session` instance, if any.
This method is called by the library prior to `connect`. This method is called by the library prior to ``connect``.
:return: The previously-saved session. :return: The previously-saved session.
""" """
@ -24,18 +24,21 @@ class Storage(abc.ABC):
""" """
Save the :class:`Session` instance to persistent storage. Save the :class:`Session` instance to persistent storage.
This method is called by the library post `disconnect`. This method is called by the library after significant changes to the session,
such as login, logout, or to persist the update state prior to disconnection.
:param session: :param session:
The session information that should be persisted. The session information that should be persisted.
""" """
@abc.abstractmethod @abc.abstractmethod
async def delete(self) -> None: async def close(self) -> None:
""" """
Delete the saved `Session`. Close the :class:`Session` instance, if it was still open.
This method is called by the library post `log_out`. This method is called by the library post ``disconnect``,
even if the call to :meth:`save` failed.
Note that both :meth:`load` and :meth:`save` may still be called after. Note that :meth:`load` may still be called after,
in which case the session should be reopened.
""" """