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

+48
View File
@@ -87,6 +87,7 @@ def test_get_updates_and_answer():
data = transport.calls[0]["data"]
assert data["offset"] == 99
assert data["timeout"] == 17
assert transport.calls[0]["timeout"] == 32
assert json.loads(data["allowed_updates"]) == ["callback_query"]
transport = FakeTransport(result=True)
@@ -203,6 +204,52 @@ def test_answer_failure_falls_back_to_text():
assert bot.edits == [10]
class Recorder:
def __init__(self):
self.events = []
def _add(self, level, event, fields):
self.events.append((level, event, fields))
def info(self, event, **fields):
self._add("info", event, fields)
def warning(self, event, **fields):
self._add("warning", event, fields)
def error(self, event, **fields):
self._add("error", event, fields)
def debug(self, event, **fields):
self._add("debug", event, fields)
class FlakyBot(FakeBot):
def __init__(self):
super().__init__([])
self.calls = 0
def get_updates(self, offset=None):
self.calls += 1
if self.calls < 3:
raise OSError("SSL: UNEXPECTED_EOF_WHILE_READING")
return []
def test_poller_backoff_and_recovery():
sleeps = []
recorder = Recorder()
bot = FlakyBot()
poller = TelegramPoller(
bot, FakeActions(), logger=recorder, sleeper=sleeps.append
)
poller.run_forever(initial_delay=3, max_delay=60, max_iterations=3)
assert bot.calls == 3
assert sleeps == [3, 6]
assert [event[0] for event in recorder.events[:2]] == ["warning", "warning"]
assert any(event[1] == "telegram.poll_recovered" for event in recorder.events)
def main():
test_format_duration()
test_send_candidates_and_chunking()
@@ -211,6 +258,7 @@ def main():
test_telegram_error_description_preserved()
test_poller_dispatch_and_authorization()
test_answer_failure_falls_back_to_text()
test_poller_backoff_and_recovery()
print("OK: Telegram 消息、分片、长轮询与回调授权测试全部通过")