mbroadst / qamqp

AMQP 0.9.1 implementation for Qt
Other
151 stars 127 forks source link

Problems with the worker example #51

Closed J4nsen closed 8 years ago

J4nsen commented 8 years ago

Hi, I was testing the worker example and had some problems.

The official worker tutorial says:

Message acknowledgments are turned on by default. In previous examples we explicitly turned them off via the no_ack=True flag. It's time to remove this flag and send a proper acknowledgment from the worker, once we're done with a task.

However, I found that m_queue->consume(); sends no ack. The rabbitmq's management interface counts "unacked" up for every received message.

Debug output:

connecting to host: "localhost" , port: 5672 -> connection#start( version_major=0, version_minor=9, mechanisms=(AMQPLAIN,PLAIN), locales=en_US ) <- connection#startOk() -> connection#tune( channel_max=0, frame_max=131072, heartbeat=60 ) <- connection#tuneOk( channelMax=0, frameMax=131072, heartbeatDelay=60 ) <- connection#open( virtualHost=/, reserved-1=0, reserved-2=0 ) -> connection#openOk() <- channel#open( channel=1, name= ) -> channel#openOk( channel=1, name=master ) <- queue#declare( queue=master, passive=0, durable=2, exclusive=0, auto-delete=8, no-wait=0 ) -> queue#declareOk( queue-name=master, message-count=0, consumer-count=0 ) <- basic#consume( queue=master, consumer-tag=, no-local=0, no-ack=0, exclusive=0, no-wait=0 ) -> queue[ master ]#consumeOk( consumer-tag=amq.ctag-M6Fw2YzXarbbo0EsUBdgUQ ) void QAmqpQueuePrivate::deliver(const QAmqpMethodFrame&) [x] Received "..." [x] Done void QAmqpQueuePrivate::deliver(const QAmqpMethodFrame&) [x] Received "..." [x] Done void QAmqpQueuePrivate::deliver(const QAmqpMethodFrame&) [x] Received "..." [x] Done

Is this the wanted behavior?

Additionally, I would recommend to use QThread::sleep instead of QTimer::singleShot, since sending a second "task" to the worker before the first one is finished, results in acking the second one two times.

void QAmqpQueuePrivate::deliver(const QAmqpMethodFrame&) [x] Received "..." void QAmqpQueuePrivate::deliver(const QAmqpMethodFrame&) [x] Received "..." [x] Done <- basic#ack( delivery-tag=2, multiple=0 ) [x] Done <- basic#ack( delivery-tag=2, multiple=0 ) -> channel#close( channel=1, name=master, reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 2, class-id=60, method-id=80, )

mbroadst commented 8 years ago

how do you figure the consume call is not being acknowledged? I see:

<- basic#consume( queue=master, consumer-tag=, no-local=0, no-ack=0, exclusive=0, no-wait=0 )
-> queue[ master ]#consumeOk( consumer-tag=amq.ctag-M6Fw2YzXarbbo0EsUBdgUQ )
mbroadst commented 8 years ago

Sorry I think I misunderstood your question, maybe you could clarify. Are you asking if, when a message is sent with no_ack=True it is the expected behavior that we do not send an ack?

mbroadst commented 8 years ago

@J4nsen also, regarding your suggestion: the example is sort of a one-off quick, and definitely contrived example. What you would really do is probably put those messages into a QList or some similar collection, then pop them off to acknowledge them. The problem stems from the fact that the message is just stored locally as m_currentMessage, that's why you end up acknowledging it twice in a row.

J4nsen commented 8 years ago

@mbroadst I was thinking that a m_queue->consume() would consume a message and send an ack to rabbitmq. For me, this is not the case. I'm sending messages from the amqp-c library tools with

./examples/amqp_sendstring localhost 5672 '' master "..."

In the webinterface of rabbitmq I can see that for the channel master, "Unacked" and "Total" have the same values.

Perhaps I'm misunderstanding something...

mbroadst commented 8 years ago

@J4nsen no consume simply indicates to the server that we would like to start consumption on this queue. Message acknowledgement is handled after this point by explicitly calling ack as demonstrated in the example. Are you seeing that the code doesn't acknowledge in un-modified form? That might be a bug indeed

mbroadst commented 8 years ago

@J4nsen I'm not seeing an issue here. I compiled the code locally and ran it, there are no outstanding unacked messages when running worker in conjunction with new-task. If you have modified this code, and find you are running into an error, please provide the code to replicate your findings.

J4nsen commented 8 years ago

@mbroadst thanks for looking into this. The example is working fine. Somehow I thought that

queue->consume(QAmqpQueue::coNoAck);

is needed if I want to ack the messages by myself, and hence

queue->consume();

would auto-ack every dequeued message.

mbroadst commented 8 years ago

@J4nsen that very well may be the case actually, you might want to confirm that between documentation of clients. I would be absolutely willing to change that if it turns out I implemented this backwards