fix(gateway): keep stale route when recovery lookup fails
This commit is contained in:
parent
f5b6112226
commit
d17daf0b12
2 changed files with 28 additions and 0 deletions
|
|
@ -1193,12 +1193,14 @@ class SessionStore:
|
|||
# end_reason not None -> session ended — prune
|
||||
if row is not None and row.get("end_reason") is not None:
|
||||
recovered_entry = None
|
||||
recovery_lookup_failed = False
|
||||
if entry.origin is not None:
|
||||
try:
|
||||
recovered_entry = self._recover_session_from_db(
|
||||
session_key=key,
|
||||
source=entry.origin,
|
||||
now=_now(),
|
||||
raise_on_lookup_error=True,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.debug(
|
||||
|
|
@ -1208,6 +1210,10 @@ class SessionStore:
|
|||
entry.session_id,
|
||||
exc,
|
||||
)
|
||||
recovery_lookup_failed = True
|
||||
|
||||
if recovery_lookup_failed:
|
||||
continue
|
||||
|
||||
# If the stale entry points at a compression-ended parent but
|
||||
# a newer live child session exists for the exact same gateway
|
||||
|
|
@ -1431,6 +1437,7 @@ class SessionStore:
|
|||
session_key: str,
|
||||
source: SessionSource,
|
||||
now: datetime,
|
||||
raise_on_lookup_error: bool = False,
|
||||
) -> Optional[SessionEntry]:
|
||||
"""Rebuild a missing session-key mapping from durable state.db data."""
|
||||
if not self._db:
|
||||
|
|
@ -1449,6 +1456,8 @@ class SessionStore:
|
|||
)
|
||||
except Exception as exc:
|
||||
logger.debug("Gateway session DB recovery failed for %s: %s", session_key, exc)
|
||||
if raise_on_lookup_error:
|
||||
raise
|
||||
return None
|
||||
if not recovered:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -151,6 +151,25 @@ class TestPruneStaleSessionsLocked:
|
|||
|
||||
assert key not in store._entries
|
||||
|
||||
def test_keeps_stale_entry_when_recovery_lookup_raises(self, tmp_path):
|
||||
"""Indeterminate recovery must not delete the only routing handle.
|
||||
|
||||
Startup pruning sees an ended parent and tries to repoint it to the
|
||||
latest live gateway child. If that recovery query raises, deleting the
|
||||
sessions.json entry loses the routing key entirely; keeping it lets the
|
||||
runtime stale guard retry recovery on the next message.
|
||||
"""
|
||||
key = "agent:main:telegram:dm:5140768830"
|
||||
db = _db_returning({"sid_parent": {"end_reason": "compression", "id": "sid_parent"}})
|
||||
db.find_latest_gateway_session_for_peer.side_effect = RuntimeError("db busy")
|
||||
store = _make_store_with_db(tmp_path, db)
|
||||
store._entries[key] = _make_entry_with_origin(key, "sid_parent")
|
||||
|
||||
store._prune_stale_sessions_locked()
|
||||
|
||||
assert key in store._entries
|
||||
assert store._entries[key].session_id == "sid_parent"
|
||||
|
||||
def test_noop_when_db_is_none(self, tmp_path):
|
||||
config = GatewayConfig(default_reset_policy=SessionResetPolicy(mode="none"))
|
||||
with patch("gateway.session.SessionStore._ensure_loaded"):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue