Skip to content

[BUG] Applicaiton hangs after AsyncCancelled #4172

@Vibrat

Description

@Vibrat

Steps to Reproduce

I am running a Telegram bot via asyncio and and the bot runs perfectly fine for 1 day or twos, then suddenly gets asyncio.AsyncCancelled exception and the application hangs.

Here is the code that I has been using.

import asyncio
import logging
import zmq
import json
import time
import traceback
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler

SUBCRIBERS = set()

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!")

async def subscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
    key = update.message.text
    if key == "/subscribe lam_bwatchers_bot":
        SUBCRIBERS.add(update.effective_chat.id)
        await context.bot.send_message(chat_id=update.effective_chat.id, text="ok, you're in")

def try_connect_zmq():
    try:
        context = zmq.asyncio.Context()
        socket = context.socket(zmq.SUB)
        socket.setsockopt(zmq.SUBSCRIBE, b"")
        socket.connect("tcp://127.0.0.1:2222")
        return socket
    except Exception:
        traceback.print_exc()
    return None

async def start_zmq(zmq_pipe, application):
    while True:
        message = await zmq_pipe.recv_json()
        for user in SUBCRIBERS:
            print("sending {message} to {user}")
            await application.bot.send_message(chat_id=user, text=json.dumps(message, indent=2))

async def run_app(api_key):
    
    application = ApplicationBuilder().token(api_key).build()
    start_handler = CommandHandler('start', start)
    subscribe_handler = CommandHandler('subscribe', subscribe)
    application.add_handler(start_handler)
    application.add_handler(subscribe_handler)
    
    ## sometimes this got async_cancel which make application not work
    ## we put it in try catch to prevent it
    zmq_pipe = try_connect_zmq()
    
    async with application:  # Calls `initialize` and `shutdown`
        await application.start()
        await application.updater.start_polling()
        await start_zmq(zmq_pipe, application)
        # Start other asyncio frameworks here
        # Add some logic that keeps the event loop running until you want to shutdown
        # Stop the other asyncio frameworks here
        await application.updater.stop()
        await application.stop()

async def start_app(options):
    await run_app(options.conf.telegram_api_key)

Expected behaviour

After getting asyncio.AsyncCancelled, the application should still run normally.

Actual behaviour

After getting this warning, it blocks all other asyncio tasks.

2024-03-25 21:27:18,548 [WARNING] Fetching updates got a asyncio.CancelledError. Ignoring as this task may onlybe closed via `Application.stop`.

Operating System

Centos 7

Version of Python, python-telegram-bot & dependencies

python-telegram-bot 21.0.1 (single-trade-50-g7714c3a)
Bot API 7.1
Python 3.9.10 (main, Nov  4 2023, 04:19:52)  [GCC 8.3.1 20190311 (Red Hat 8.3.1-3)]

Relevant log output

2024-03-25 21:27:14,965 [INFO] HTTP Request: POST https://api.telegram.org/bot6461521072:AAHYRcFVmxkdQ9W5DHmmkGO_PJXF85gW-tU/getUpdates "HTTP/1.1 200 OK"
2024-03-25 21:27:18,548 [WARNING] Fetching updates got a asyncio.CancelledError. Ignoring as this task may onlybe closed via `Application.stop`.

Additional Context

Additionally, I think the problem lines in __process_update_wrapper not being able to catch with any exception, when asyncio.AsyncCancelled, job queue could not be marked done which block the entire asyncio.

    async def __process_update_wrapper(self, update: object) -> None:
        await self._update_processor.process_update(update, self.process_update(update))
        self.update_queue.task_done()

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