Skip to content

fix: prevent task GC in AsyncTeleBot by tracking background tasks - #2574

Open
gilangjavier wants to merge 2 commits into
eternnoir:masterfrom
gilangjavier:fix/background-task-leak
Open

gilangjavier wants to merge 2 commits into
eternnoir:masterfrom
gilangjavier:fix/background-task-leak

Conversation

@gilangjavier

@gilangjavier gilangjavier commented Mar 18, 2026

Copy link
Copy Markdown

This fix addresses the issue where was called without storing a strong reference to the task, leading to potential premature garbage collection. We now maintain a set of background tasks and add a done callback to discard them upon completion.Fixes #2572

@gilangjavier

Copy link
Copy Markdown
Author

I checked this PR and currently no CI checks are being reported on the branch (gh pr checks returns none), so status stays UNSTABLE.

Could a maintainer confirm how CI should be triggered for external contributor PRs in this repo? If there is a label/command/manual trigger needed, I can follow it.

@Badiboy
Badiboy requested a review from Copilot March 19, 2026 06:02
@Badiboy

Badiboy commented Mar 19, 2026

Copy link
Copy Markdown
Collaborator

Triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a potential asyncio garbage-collection issue in AsyncTeleBot polling by retaining strong references to “fire-and-forget” tasks created for update processing, aligning with Python’s asyncio.create_task() guidance.

Changes:

  • Add an instance-level _background_tasks set to retain created asyncio.Task objects.
  • Track each process_new_updates() task and discard it from the set when it completes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread telebot/async_telebot.py Outdated
Comment on lines +457 to +459
task = asyncio.create_task(self.process_new_updates(updates))
self._background_tasks.add(task)
task.add_done_callback(self._background_tasks.discard)
Comment thread telebot/async_telebot.py Outdated
Comment on lines +457 to +459
task = asyncio.create_task(self.process_new_updates(updates))
self._background_tasks.add(task)
task.add_done_callback(self._background_tasks.discard)
Comment thread telebot/async_telebot.py Outdated
self.middlewares = []

self._user = None # set during polling
self._background_tasks = set()
@gilangjavier

Copy link
Copy Markdown
Author

Follow-up with exact fixes for Copilot feedback:

  • Added explicit typing for background task tracking: _background_tasks: set[asyncio.Task[Any]].
  • Replaced the discard-only callback with _on_background_task_done + _process_background_task_result so task exceptions are always retrieved and routed through _handle_exception/logger (prevents "Task exception was never retrieved").
  • Added _shutdown_background_tasks() and call it in polling finally before close_session(): wait briefly for in-flight update tasks, then cancel/drain remaining tasks before closing aiohttp session.

Commit: a01eda6

Please re-review when convenient 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Potential Bug: asyncio.create_task lacks strong references in telebot.AsyncTeleBot._process_polling

3 participants