fix(telegram): drop pending updates on first poll - #211
Merged
Merged
Conversation
Discard Telegram server backlog when an adapter instance first starts polling so offline history does not flush into the pipeline and stall the per-session rate limiter. Keep pending updates after an in-process client rebuild so brief disconnects can catch up. Fixes #210 AI-Generated: true Generated-At: 2026-09-17T10:41:59Z
BegoniaHe
commented
Sep 17, 2026
BegoniaHe
left a comment
Member
Author
There was a problem hiding this comment.
AI-assisted review
独立于作者 ## Agent note 的评审。未代维护者 Approve,也未合并。
结论:可以合入。 无阻断缺陷。改动范围与 #210 验收标准对齐。
做了什么
- 对照
master...pr-211的 4 个文件、Issue #210、RateLimitStage、PlatformManager.reload()、以及本机python-telegram-bot的Updater.start_polling/_bootstrap。 - 本会话运行:
uv run pytest tests/unit/platform/test_telegram_adapter.py::test_telegram_polling_allowed_updates_are_explicit tests/unit/platform/test_telegram_adapter.py::test_telegram_run_rebuilds_application_after_repeated_polling_errors tests/unit/platform/test_telegram_adapter.py::test_telegram_run_rebuilds_fresh_application_after_recreate_init_failure
3 passed。CI 上 Linux/macOS blocking pytest、coverage、ruff、quality 已绿;评审时 Windows blocking 与部分 runtime job 仍 pending,不作为本会话已验证项。
正确性
根因成立:start_polling() 未传 drop_pending_updates 时 PTB 默认为 False,会把 Telegram 约 24 小时积压灌入 pipeline。默认 platform_settings.rate_limit 为 30/60 + stall,同一 UMO 会持锁睡眠约 60.3s。
实现匹配提案:
- 适配器实例首次
start_polling传True。 - 赋值
self._drop_pending_updates = False在await start_polling(...)成功返回之后。PTB 会先_bootstrap()(delete_webhook(drop_pending_updates=...))再标记 ready,因此成功返回意味着积压已经丢弃。 start_polling抛错时标志仍为True,外层except Exception重建后再丢一次,正确。_recreate_application()与异常路径的_build_application()都发生在首次成功轮询之后,因此进程内追赶用False。PlatformManager.reload()会 terminate 再 new instance,Dashboard 停用/启用与进程重启一样会丢积压;这覆盖 Issue 里「离线后在面板添加适配器」的场景。- Telegram 适配器只有 polling,没有 webhook 第二路径。
- 未改
RateLimitStage、其他适配器、OpenAPI。
不需要 BREAKING CHANGE:。先前吞积压是缺陷,不是已文档化的承诺。PR 兼容性段已经写明操作者可见变化。
测试与文档
- 首次
True/ 重建后False挂在两条已有重建测试上,契约测试补了drop_pending_updates=True。够用,不必再加函数。 - 中英文平台页都写了首次丢弃与进程内追赶。英文「flushed into the pipeline and the per-session rate limiter」稍别扭,中文更准确;不阻断。
残留风险(不阻断)
- 首次成功轮询之后,进程一直活着但网络中断很久,恢复时
drop_pending_updates=False。新Updater的 offset 会重置,Telegram 服务端未确认队列会整段回放。Issue 明确接受「短缺口追赶」;常见「停机一整晚再启动」仍走新实例 +True。若以后要收紧,应按缺口时长丢弃,而不是再加配置开关。 - 文档只写了进程重启丢积压,未写 Dashboard 重载同样丢。行为正确,必要时可补一句。
- 没有单独覆盖「首次
start_polling失败后重试仍为True」。代码路径是 await 之后才翻转,风险低。
流程
fix(telegram): 标题、Fixes #210、AI footer、单一 ## Agent note 都符合 AI_POLICY.md。人类维护者仍需自己审并决定合并。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Telegram polling ingested offline pending updates as live messages. A backlog in one chat could stall that session for about 60 seconds in
RateLimitStageand cause the bot to answer stale history. This change drops pending updates on the firststart_pollingof an adapter instance, and keeps them after an in-process client rebuild.Related issue
Fixes #210
Root cause
updater.start_polling()did not passdrop_pending_updates. python-telegram-bot defaults toFalse, so Telegram's 24-hour pending queue was converted into pipeline events. The inbound limiter is per UMO with a 30/60 stall window, so one busy chat's backlog slept on the session lock.Reproduction
Implementation notes
Do not change
RateLimitStage. First successfulstart_pollingusesdrop_pending_updates=True; later in-process polling after_recreate_application()usesFalseso a short network gap can catch up. No new config switch. Process restart still drops backlog.Validation
Ruff format/check passed. The three polling tests passed. Prettier check passed on the two docs pages.
make checkand the full blocking pytest suite were not run.Compatibility and risk
User-visible: messages sent while AstrBot was stopped are no longer processed after process start or first adapter connect. In-process polling recovery still replays the gap. No public API, Dashboard protocol, or OpenAPI change.
Checklist
docs/zh/anddocs/en/when needed.docs/public/openapi.json, and tests change together when routes or schemas change.pyproject.toml,requirements.txt, anduv.locktogether.!and aBREAKING CHANGE:footer.Agent note
Goal: stop Telegram startup backlog from stalling the per-UMO inbound limiter and from being answered as live traffic. Touched
tg_adapter.py, the polling tests intest_telegram_adapter.py, and both Telegram platform docs. Checks actually run are listed above; fullmake check/ blocking pytest were not. Residual risk: operators who wanted crash-restart catch-up will now drop that backlog by design. Tools: OpenCode / GPT. This write-up is not the required separate AI-assisted review.