from __future__ import annotations import asyncio import logging logger = logging.getLogger(__name__) class PollingScheduler: def __init__(self, poll_func, interval: int = 30): self._poll_func = poll_func self._interval = interval self._task: asyncio.Task | None = None self._running = False async def start(self) -> None: self._running = True self._task = asyncio.create_task(self._run_loop()) logger.info("Help Scout polling scheduler started: interval=%ds", self._interval) async def stop(self) -> None: self._running = False if self._task: self._task.cancel() try: await self._task except asyncio.CancelledError: pass logger.info("Help Scout polling scheduler stopped") async def _run_loop(self) -> None: backoff = 1 max_backoff = 300 while self._running: try: await self._poll_func() backoff = 1 except asyncio.CancelledError: break except Exception: logger.exception("Help Scout polling error — backing off %ds", backoff) await asyncio.sleep(backoff) backoff = min(backoff * 2, max_backoff) continue await asyncio.sleep(self._interval)