mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-10 18:22:20 +02:00
fix: discover sessions from persisted messages (#5938)
* fix(session): discover sessions from persisted messages Use indexed chat-row existence instead of stale derived message_count metadata during startup discovery, then repair the bounded in-memory counts so lazy hydration remains correct. Keep truly empty sessions excluded and cover stale-low and stale-high counts with real SQLite. * test(session): isolate discovery database * test(session): use manager database metadata
This commit is contained in:
+17
-1
@@ -14,6 +14,8 @@ import logging
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from typing import Dict, Optional
|
||||
|
||||
from sqlalchemy import func
|
||||
|
||||
from .database import Session as DbSession, ChatMessage as DbChatMessage, Document as DbDocument, SessionLocal, utcnow_naive
|
||||
from .models import Session, ChatMessage
|
||||
from src.attachment_refs import persistable_message_content
|
||||
@@ -92,14 +94,28 @@ class SessionManager:
|
||||
try:
|
||||
db_sessions = db.query(DbSession).filter(
|
||||
DbSession.archived == False,
|
||||
DbSession.message_count > 0,
|
||||
DbSession.messages.any(),
|
||||
).order_by(DbSession.last_accessed.desc()).limit(100).all()
|
||||
|
||||
# message_count is derived metadata and can drift after interrupted
|
||||
# or legacy writes. Count only the bounded discovery set so startup
|
||||
# remains metadata-only while lazy hydration sees an authoritative
|
||||
# positive count for every discovered non-empty session.
|
||||
message_counts = {}
|
||||
if db_sessions:
|
||||
message_counts = dict(
|
||||
db.query(DbChatMessage.session_id, func.count(DbChatMessage.id))
|
||||
.filter(DbChatMessage.session_id.in_([row.id for row in db_sessions]))
|
||||
.group_by(DbChatMessage.session_id)
|
||||
.all()
|
||||
)
|
||||
|
||||
loaded_count = 0
|
||||
for db_session in db_sessions:
|
||||
try:
|
||||
session = self._db_to_session_meta(db_session)
|
||||
if session is not None:
|
||||
session.message_count = message_counts[db_session.id]
|
||||
self.sessions[db_session.id] = session
|
||||
loaded_count += 1
|
||||
except Exception as e:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
"""Real-SQLite regressions for session discovery with stale derived counts."""
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.pool import NullPool
|
||||
|
||||
import core.session_manager as session_manager
|
||||
|
||||
|
||||
def _make_manager(db_path, monkeypatch):
|
||||
engine = create_engine(
|
||||
f"sqlite:///{db_path}",
|
||||
connect_args={"check_same_thread": False},
|
||||
poolclass=NullPool,
|
||||
)
|
||||
session_manager.DbSession.metadata.create_all(bind=engine)
|
||||
session_local = sessionmaker(
|
||||
bind=engine,
|
||||
autoflush=False,
|
||||
autocommit=False,
|
||||
)
|
||||
monkeypatch.setattr(session_manager, "SessionLocal", session_local)
|
||||
return session_manager.SessionManager(), session_manager
|
||||
|
||||
|
||||
def test_discovery_uses_persisted_rows_and_repairs_cached_count(tmp_path, monkeypatch):
|
||||
from core.models import ChatMessage
|
||||
|
||||
manager, session_manager = _make_manager(
|
||||
tmp_path / "session-discovery.db", monkeypatch
|
||||
)
|
||||
for session_id in ("stale-low", "empty", "stale-high"):
|
||||
manager.create_session(
|
||||
session_id=session_id,
|
||||
name=session_id,
|
||||
endpoint_url="http://example.invalid",
|
||||
model="test-model",
|
||||
rag=False,
|
||||
owner="tester",
|
||||
)
|
||||
manager.add_message("stale-low", ChatMessage("user", "persisted message"))
|
||||
|
||||
db = session_manager.SessionLocal()
|
||||
try:
|
||||
db.query(session_manager.DbSession).filter(
|
||||
session_manager.DbSession.id == "stale-low"
|
||||
).update({"message_count": 0})
|
||||
db.query(session_manager.DbSession).filter(
|
||||
session_manager.DbSession.id == "stale-high"
|
||||
).update({"message_count": 7})
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
restarted = session_manager.SessionManager()
|
||||
|
||||
assert set(restarted.sessions) == {"stale-low"}
|
||||
assert restarted.sessions["stale-low"].history == []
|
||||
assert restarted.sessions["stale-low"].message_count == 1
|
||||
|
||||
hydrated = restarted.get_session("stale-low")
|
||||
assert [message.content for message in hydrated.history] == ["persisted message"]
|
||||
Reference in New Issue
Block a user