refactor(gateway): release turn leases by token identity only

Every `TurnLeaseToken` is now constructed by `SessionTurnLeaseRegistry.acquire`
with its concrete `_SessionLease`, so `release()` no longer needs the
`getattr(token, "lease", None) or self._leases.get(...)` fallback that #107013
left in place. Make `lease` a required constructor argument and resolve the
lease from the token alone; the mapping lookup could only ever return the same
object (or a stale alias after rotation, which is exactly the case identity
release exists to avoid).
This commit is contained in:
kshitijk4poor
2026-09-11 11:02:38 +05:30
committed by kshitij
parent 317f4079a9
commit 18da3f673a
+4 -4
View File
@@ -45,9 +45,11 @@ class TurnLeaseToken:
__slots__ = ("session_id", "owner_key", "generation", "released", "lease")
def __init__(self, session_id: str, owner_key: str, generation: int, lease: Optional["_SessionLease"] = None) -> None:
def __init__(self, session_id: str, owner_key: str, generation: int, lease: "_SessionLease") -> None:
self.session_id, self.owner_key, self.generation = session_id, owner_key, generation
self.released = False
# The concrete lease, so release resolves by identity even after a rotation re-aliases
# ``session_id`` (both ids map to this same lease).
self.lease = lease
def __repr__(self) -> str: # pragma: no cover - debug aid
@@ -166,9 +168,7 @@ class SessionTurnLeaseRegistry:
if token is None or token.released:
return False
token.released = True
lease = getattr(token, "lease", None) or self._leases.get(token.session_id)
if lease is None:
return False
lease = token.lease
if lease.holder is not token:
logger.debug("turn lease release skipped on session %s: token (key %s gen %s) is not "
"the current holder", token.session_id, token.owner_key, token.generation)