mosquito / aio-pika

AMQP 0.9 client designed for asyncio and humans.
https://aio-pika.readthedocs.org/
Apache License 2.0
1.24k stars 189 forks source link

Channel Closed Exception #150

Open josephbiko opened 6 years ago

josephbiko commented 6 years ago

I have the following piece of code

class NewQ:
    def __init__(self, name,durable=False):
        self.name = name
        self.q = None
        self.durable = durable
        self.channel = None

    async def __aenter__(self):
        await connect_to_RMQ()
        self.channel = await get_new_channel()
        self.q = await self.channel.declare_queue(self.name)
        q=await self.channel.declare_queue("test")
        await q.delete()

        __log__.debug("%s has been created", self.name)
        return (self.q,self.channel)

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if not self.durable:
            await self.q.delete()
            __log__.debug("%s has been deleted", self.name)
        await self.channel.close()

Now everytime the aexit (await self.q.delete()) is reached, i get an ChannelClosed Exception, however, the channel is listed as open right before (Channel._channel._state==2). Am I doing something wrong?

MichalJagiello commented 5 years ago

I have the same issue. I have edited an example for easier debugging:

import aio_pika
import asyncio

async def main(loop):
    connection = await aio_pika.connect_robust("amqp://guest:guest@127.0.0.1/", loop=loop)

    queue_name = "test_queue"

    # Creating channel
    channel = await connection.channel()    # type: aio_pika.Channel

    # Declaring queue
    queue = await channel.declare_queue(queue_name, auto_delete=True)   # type: aio_pika.Queue

    async for message in queue:
        with message.process():
            print(message.body)

            if queue.name in message.body.decode():
                break

    await queue.delete()  # Exception is raised here

    queue = await channel.declare_queue(queue_name, auto_delete=True)

    async for message in queue:
        with message.process():
            print(message.body)

            if queue.name in message.body.decode():
                break

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main(loop))
    loop.close()

Exception: aio_pika.pika.exceptions.ChannelClosed: (406, "PRECONDITION_FAILED - queue 'test_queue' in vhost '/' in use")

MichalJagiello commented 5 years ago

If I change my example code and use await queue.delete(if_empty=False, if_unused=False) I have an exception aio_pika.pika.exceptions.ChannelClosed when I want to declare queue second time