I want process messages in few threads but i\'m getting error during execute this code:
from __future__ import with_statement
import pika
import sys
from pika.ad
There is a bug with your code. You share a channel across threads. This is not supported by pika (see FAQ). You have 2 options:
no_ack=True
flag in basic_get(...)
and do not use the channel object in thread's function doWork(...)
If you need to ACK message only after you have finished your work, then let the main thread (the while True:
loop) handle the message ack (and not the worker thread). Below is a modified version of your code that does that.
from __future__ import with_statement
import pika
import sys
from pika.adapters.blocking_connection import BlockingConnection
from pika import connection, credentials
import time
import threading
import random
from pika.adapters.select_connection import SelectConnection
from pika.connection import Connection
import traceback
from Queue import Queue, Empty
def doWork(body, args, channel, ack_queue):
time.sleep(random.random())
ack_queue.put(args.delivery_tag)
def doAck(channel):
while True:
try:
r = ack_queue.get_nowait()
except Empty:
r = None
if r is None:
break
try:
channel.basic_ack(delivery_tag=r)
except:
traceback.print_exc()
auth = credentials.PlainCredentials(username="guest", password="guest")
params = connection.ConnectionParameters(host="localhost", credentials=auth)
conn = BlockingConnection(params)
channel = conn.channel()
# Create a queue for the messages that should be ACKed by main thread
ack_queue = Queue()
while True:
time.sleep(0.03)
try:
doAck(channel)
method_frame, header_frame, body = channel.basic_get(queue="test_queue")
if method_frame.NAME == 'Basic.GetEmpty':
continue
t = threading.Thread(target=doWork, args=[body, method_frame, channel, ack_queue])
t.setDaemon(True)
t.start()
except Exception, e:
traceback.print_exc()
continue