вс кли
self.suppress_recv_logging: bool = False
self.received_messages_count: int = 0
await self.recv_queue.put(result_message)
self.received_messages_count += 1
кипер
async def _keepalive_async(group_state: dict, stop_event: threading.Event) -> None:
"""
Цикл фоновой подписки: подключение -> подписка -> слив очереди.
При обрыве соединения или ошибке создаёт новый WebSocketClient и
подписывается заново, пока не выставлен stop-сигнал.
"""
while not stop_event.is_set():
ws_client = init_ws_stand_client(group_state)
ws_client.suppress_recv_logging = True
try:
async with ws_client as client:
await client.invoke(WS_Const.KEEPALIVE_SUBSCRIPTION_REQUEST, [])
logger.info(
"[KEEPER] фоновая подписка запущена: %s",
WS_Const.KEEPALIVE_SUBSCRIPTION_REQUEST,
)
connected_at = time.monotonic()
last_clean = time.monotonic()
last_heartbeat = time.monotonic()
last_received = client.received_messages_count
while not stop_event.is_set():
await asyncio.sleep(WS_Const.KEEPALIVE_POLL_INTERVAL_SECONDS)
if stop_event.is_set():
break
now = time.monotonic()
if now - last_clean >= WS_Const.KEEPALIVE_QUEUE_CLEAN_INTERVAL_SECONDS:
client.clear_queue()
last_clean = now
if now - last_heartbeat >= WS_Const.KEEPALIVE_HEARTBEAT_INTERVAL_SECONDS:
received_now = client.received_messages_count
logger.info(
"[KEEPER] heartbeat: соединение активно=%s, аптайм=%.0fс, "
"сообщений за минуту=%d (всего=%d)",
client.is_connected,
now - connected_at,
received_now - last_received,
received_now,
)
last_received = received_now
last_heartbeat = now
if not client.is_connected:
logger.warning("[KEEPER] соединение потеряно, переподключаемся")
break
except asyncio.CancelledError:
break
except Exception as error:
if stop_event.is_set():
break
logger.warning(
"[KEEPER] ошибка соединения/подписки: %s. Повтор через %s с",
error,
WS_Const.KEEPALIVE_RECONNECT_INTERVAL_SECONDS,
)
await asyncio.sleep(WS_Const.KEEPALIVE_RECONNECT_INTERVAL_SECONDS)
арх
KEEPALIVE_STOP_JOIN_TIMEOUT_SECONDS: float = 5.0 # таймаут join() фонового потока при остановке
KEEPALIVE_HEARTBEAT_INTERVAL_SECONDS: float = 60.0 # период heartbeat-лога фоновой подписки