Search code examples
pythonmultithreadingrabbitmqpikapython-pika

Pika threaded execution gets error - 505, 'UNEXPECTED_FRAME


I'm aware that pika is not thread safe, i was trying to work around using a lock to access to channel but still get error:

pika.exceptions.ConnectionClosed: (505, 'UNEXPECTED_FRAME - expected content header for class 60, got non content header frame instead')

PS i cannot use a different channel.

what could i do? Thank you for help in advance


Solution

  • You need to redesign your application or choose another Rabbitmq library than Pika. Locks do not make Pika thread safe. Each thread needs to have a separate connection.

    You have a couple of options, but none of them will be as simple as using a lock.

    One would be to replace Pika with Kombu. Kombu is thread safe but the interface is rather different from Pika (simpler in my opinion but this is subjective).

    If you want to keep using Pika, then you need to redesign your Rabbit interface. I do not know why you "cannot" use a different channel. But one possible way of doing this would be to have a single thread interfacing with Rabbit, and that thread would interact with worker threads doing tasks with the received data, and you would communicate via queues with them. This way your Rabbit thread would read data, send the received data to a worker in a queue, receive answers from workers via another queue and then submitting them to rabbit as responses.

    You might also be able to untangle something in your communications protocol so that you actually can use a different channel and each thread can interface rabbit independently with their own connections and channels. This is the method I generally use.

    Yet another candidate would be to get rid of threads and start using async methods instead. Your application may or may not be suitable for this.

    But there is no simple workaround, and you will eventually encounter weird behaviour or exceptions if you try to share Pika objects between threads.