fix(telegram): back off on transient polling failures

Give getUpdates a wider HTTP timeout than the long-poll window, log transient SSL/network disconnects as warnings, apply exponential backoff with recovery logging, and only escalate to error after five consecutive failures.
This commit is contained in:
kairee committed 2026-10-31 22:01:05 +08:00
1 parent 2d42d8ed55
commit 71a0e8c1d6
3 files changed
+96 -7

No files matched your search

+34 -4
View File
@@ -88,11 +88,41 @@ class TelegramPoller:
self._log("warning", "telegram.answer_failed", error=str(exc))
return False
def run_forever(self, stop_event=None) -> None:
def run_forever(
self,
stop_event=None,
*,
initial_delay: float = 3.0,
max_delay: float = 60.0,
max_iterations: int | None = None,
) -> None:
offset: int | None = None
failures = 0
delay = initial_delay
iterations = 0
while stop_event is None or not stop_event.is_set():
try:
offset = self.run_once(offset)
except Exception as exc: # noqa: BLE001 长轮询失败后退避重试
self._log("error", "telegram.poll_failed", error=str(exc))
self._sleep(3)
except Exception as exc: # noqa: BLE001 长轮询瞬时断连后退避重试
failures += 1
level = "error" if failures >= 5 else "warning"
self._log(
level, "telegram.poll_failed",
error=str(exc), failures=failures, retry_in=delay,
)
if stop_event is not None:
if stop_event.wait(delay):
break
else:
self._sleep(delay)
delay = min(delay * 2, max_delay)
else:
if failures:
self._log(
"info", "telegram.poll_recovered", failures=failures
)
failures = 0
delay = initial_delay
iterations += 1
if max_iterations is not None and iterations >= max_iterations:
break