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.
Bug Description
In the asynchronous polling loop of
AsyncTeleBot(e.g., insidetelebot.AsyncTeleBot._process_polling), incoming updates are dispatched toprocess_new_updatesusingasyncio.create_task(). However, the resultingasyncio.Taskobject is not assigned to any variable or collection, meaning no strong reference is kept. (See below code block, also see here)According to the official Python
asynciodocumentation, 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:
Potential Solution
Add a queue to
AsyncTeleBotto storeasyncio.Taskcreated viaasyncio.create_task()is enough to solve the problem.If it is ok, I would be happy to create a PR to fix it.