various/stale

This commit is contained in:
2026-01-25 13:14:00 -05:00
parent 10ccf8c8eb
commit 97fd7dd67d
14 changed files with 501 additions and 64 deletions

View File

@@ -228,6 +228,10 @@ class Lighting:
if self._state.session.closed:
return False
if not self._is_tcp_connected():
logger.info("Cync TCP manager not connected; will reconnect")
return False
# Check token expiry
if self._is_token_expired():
logger.info("Token expired or expiring soon")
@@ -235,6 +239,35 @@ class Lighting:
return True
def _is_tcp_connected(self) -> bool:
"""Best-effort check that the pycync TCP connection is alive."""
client = getattr(self._state.cync_api, "_command_client", None)
if not client:
return False
tcp_manager = getattr(client, "_tcp_manager", None)
if not tcp_manager:
return False
# If login was never acknowledged or was cleared, treat as disconnected
if not getattr(tcp_manager, "_login_acknowledged", False):
return False
writer = getattr(tcp_manager, "_writer", None)
reader = getattr(tcp_manager, "_reader", None)
# If underlying streams are closed, reconnect
if writer and writer.is_closing():
return False
if reader and reader.at_eof():
return False
# Some versions expose a _closed flag
if getattr(tcp_manager, "_closed", False):
return False
return True
def _is_token_expired(self) -> bool:
"""Check if token is expired or will expire soon."""
if not self._state.user:
@@ -418,11 +451,21 @@ class Lighting:
"""Background task to monitor connection health and refresh tokens."""
while True:
try:
await asyncio.sleep(300) # Check every 5 minutes
await asyncio.sleep(60) # Check every minute
needs_reconnect = False
# Proactively refresh if token is expiring
if self._is_token_expired():
logger.info("Token expiring, proactively reconnecting...")
needs_reconnect = True
# Reconnect if TCP connection looks dead
if not self._is_tcp_connected():
logger.warning("Cync TCP connection lost; reconnecting...")
needs_reconnect = True
if needs_reconnect:
try:
await self._connect(force=True)
except Exception as e: