"""蓝绿单轮选主的 Provider 巡检与开发者邮件。""" from __future__ import annotations import os from core.storage import get_engine from .registry import get_provider from .service import due_provider_ids, test_current_credentials from .testing import TestResult _LOCK_SQL = "SELECT pg_try_advisory_lock(31331, 2)" _UNLOCK_SQL = "SELECT pg_advisory_unlock(31331, 2)" def send_notification(provider_id: str, event: str, result: TestResult) -> None: provider = get_provider(provider_id) label = "恢复正常" if event == "recovered" else result.detail print(f"[provider] {provider_id} {event}: {label}") email = os.getenv("ZCBOT_DEVELOPER_EMAIL", "").strip() if not email: return try: from tools.send_email import send_email_smtp, smtp_configured if smtp_configured(): send_email_smtp( email, f"[zcbot] {provider.display_name} {label}", f"Provider: {provider.display_name}\n状态: {event}\n详情: {result.detail}", ) except Exception as exc: # noqa: BLE001 - 告警失败不得影响业务状态 print(f"[provider] notification failed: {type(exc).__name__}") def run_due_checks() -> int: engine = get_engine() with engine.connect() as connection: claimed = bool(connection.exec_driver_sql(_LOCK_SQL).scalar()) if not claimed: return 0 try: count = 0 for provider_id in due_provider_ids(): try: test_current_credentials(provider_id, notify=send_notification) count += 1 except Exception as exc: # noqa: BLE001 - 单 Provider 隔离 print(f"[provider] {provider_id} check failed: {type(exc).__name__}") return count finally: connection.exec_driver_sql(_UNLOCK_SQL)