Skip to content

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

Description

@fshp971

Bug Description

In the asynchronous polling loop of AsyncTeleBot (e.g., inside telebot.AsyncTeleBot._process_polling), incoming updates are dispatched to process_new_updates using asyncio.create_task(). However, the resulting asyncio.Task object is not assigned to any variable or collection, meaning no strong reference is kept. (See below code block, also see here)

        try:
            while self._polling:
                try:
                    updates = await self.get_updates(offset=self.offset, allowed_updates=allowed_updates, timeout=timeout, request_timeout=request_timeout)
                    if updates:
                        self.offset = updates[-1].update_id + 1
                        # noinspection PyAsyncCall
                        asyncio.create_task(self.process_new_updates(updates)) # Seperate task for processing updates
                    if interval: await asyncio.sleep(interval)
                    error_interval = 0.25 # drop error_interval if no errors

According to the official Python asyncio documentation, the event loop only maintains weak references to tasks. If a task yields control back to the event loop (e.g., awaiting network I/O or a sleep), Python's Garbage Collector (GC) may destroy the unreferenced task mid-execution. This results in the task disappearing silently without raising any exceptions.

I also copy the official explanation from Python documentation (https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task) here to better illustrate the risk:

Important: Save a reference to the result of this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn’t referenced elsewhere may get garbage collected at any time, even before it’s done. For reliable “fire-and-forget” background tasks, gather them in a collection:

Potential Solution

Add a queue to AsyncTeleBot to store asyncio.Task created via asyncio.create_task() is enough to solve the problem.

If it is ok, I would be happy to create a PR to fix it.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions