Bug 913448 - invoking Receiver::fetch() in a loop for slow producer causes only first <prefetch> messages received
Summary: invoking Receiver::fetch() in a loop for slow producer causes only first <pre...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: qpid-cpp
Version: 2.3
Hardware: All
OS: Linux
medium
medium
Target Milestone: 3.0
: ---
Assignee: Gordon Sim
QA Contact: Leonid Zhaldybin
URL:
Whiteboard:
Depends On:
Blocks: 923452
TreeView+ depends on / blocked
 
Reported: 2013-02-21 09:36 UTC by Pavel Moravec
Modified: 2018-12-02 18:29 UTC (History)
9 users (show)

Fixed In Version: qpid-java-0.22-1.el5, qpid-java-0.22-2.el6
Doc Type: Bug Fix
Doc Text:
It was discovered that if a fetch timed-out, information about the current credit window quota was cleared from the broker. This prevented the credit window reported by the client to be moved forward by the broker, and prevent a receiver from receiving messages even though there were messages available on the queue. The broker is now notified which messages have been received whenever a fetch times out. The credit window is now always moved forward correctly, and messages continue to be received when available.
Clone Of:
: 923452 (view as bug list)
Environment:
Last Closed: 2014-09-24 15:06:29 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
Reproducer (1.68 KB, application/gzip)
2013-02-21 09:40 UTC, Pavel Moravec
no flags Details
Patch proposal (2.18 KB, patch)
2013-02-22 08:16 UTC, Pavel Moravec
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Apache JIRA QPID-4595 0 None None None Never
Red Hat Product Errata RHEA-2014:1296 0 normal SHIPPED_LIVE Red Hat Enterprise MRG Messaging 3.0 Release 2014-09-24 19:00:06 UTC

Description Pavel Moravec 2013-02-21 09:36:40 UTC
Description of problem:
Having a scenario with a slow producer and a consumer periodically running Receiver::fetch() method (for timeout lesser than forever), the consumer gets just first N messages where N is the size of prefetch / capacity, and then nothing - despite there are new messages on the broker.


Version-Release number of selected component (if applicable):
qpid-cpp-client*-0.18-14


How reproducible:
100%


Steps to Reproduce:
1. Unpack attached tarball
2. make
3. in one terminal, create queue and start producer (that waits 15 seconds to kick-off consumer first):
./setup
4. in another terminal, start consumer:
./read

  
Actual results:
When producer starts to produce messages, the consumer gets just first 10 messages (or whatever is set in receiver.setCapacity()). Later on, despite there are new messages in the queue, receiver does not get any.


Expected results:
Receiver gets further messages when some occurr on the broker.


Additional info:
See next update for in-depth analysis.

Comment 1 Pavel Moravec 2013-02-21 09:40:31 UTC
Created attachment 700414 [details]
Reproducer

Comment 2 Pavel Moravec 2013-02-21 10:00:01 UTC
In-depth analysis:

Client library does not send session.completed when expected so. As default flow mode - window - is used, to acknowledge received messages (or compelte their delivery), session.complete has to be sent by the client. Quoting AMQP spec and Command: message.set-flow-mode:

"(for Window based flow control) Completion of the transfer command with session.completed is the only way credit is implicitly updated".

While the client never sends session.completed method, just only these (qpid client trace logs):

2013-02-21 09:46:47 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {MessageAcceptBody: transfers={ [4,4] }; }]
2013-02-21 09:46:47 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {SessionFlushBody: completed=1; }]
2013-02-21 09:46:47 [Network] trace RECV [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {SessionCompletedBody: commands={ [47,51] }; timely-reply=1; }]
2013-02-21 09:46:47 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {SessionKnownCompletedBody: commands={ [47,51] }; }]
2013-02-21 09:46:49 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {MessageFlushBody: destination=ToApp; }]
2013-02-21 09:46:49 [Network] trace RECV [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {SessionCompletedBody: commands={ [52,52] }; }]
No messages pending in queue 
2013-02-21 09:46:49 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {MessageSetFlowModeBody: destination=ToApp; flow-mode=1; }]
2013-02-21 09:46:49 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {MessageFlowBody: destination=ToApp; unit=0; value=10; }]
2013-02-21 09:46:49 [Network] trace SENT [[[::1]:49334-localhost:5672]]: Frame[BEbe; channel=1; {MessageFlowBody: destination=ToApp; unit=1; value=4294967295; }]
2013-02-21 09:46:50 [Network] trace RECV [[[::1]:49334-localhost:5672]]: Frame[Bbe; channel=1; {MessageTransferBody: destination=ToApp; accept-mode=0; acquire-mode=0; }]
2013-02-21 09:46:50 [Network] trace RECV [[[::1]:49334-localhost:5672]]: Frame[be; channel=1; header (31 bytes); properties={{MessageProperties: content-length=3; }{DeliveryProperties: exchange=App.Ex; }}]
2013-02-21 09:46:50 [Network] trace RECV [[[::1]:49334-localhost:5672]]: Frame[Ebe; channel=1; content (3 bytes) xxx]
2013-02-21 09:46:50 [Client] debug Delivered {MessageTransferBody: destination=ToApp; accept-mode=0; acquire-mode=0; } header (31 bytes); properties={{MessageProperties: content-length=3; }{DeliveryProperties: exchange=App.Ex; }}

See the client sends just:
message.accept
session.flush
session.known-completed
message.set-flow-mode
message.flow

Reading this: why the client sends message.accept as that does not really complete the message delivery? (comparing with qpid-receive trace, qpid-receive sends session.completed after N/2 messages received for N=prefetch, nothing else). Is not the client behaving rather than in credit flow mode (while setting window mode in message.set-flow-mode)?

Curiously, changing fetch timeout to FOREVER in read.cpp, the client is getting all messages as expected and invokes session.completed as expected (after N/2 msgs received).

Comment 3 Pavel Moravec 2013-02-22 08:16:51 UTC
Created attachment 701038 [details]
Patch proposal

Root cause of the bug: see qpid::client::amqp0_10::ReceiverImpl::fetchImpl method:

After sending message.flush, the consumer's credit is zero so it re-sets it by calling startFlow(ScopedLock) method. BUT session.complete command is not sent to really update the credit.

Invoking that requires received(message); method call. To perform the call properly, startFlow can't update window - thats why startFlow has a new bool parameter.

Comment 5 Pavel Moravec 2013-02-26 07:31:46 UTC
IMHO no problem adding the customer to Cc here - that is usually done and this BZ has nothing sensitive (and I assume it wont have anything so).

Dan, ask the customer for bugzilla login (email address) and add the email to Cc.

Comment 6 Pavel Moravec 2013-03-12 17:46:13 UTC
Gordon Sim resolved QPID-4595 in 0.21 (Fixed by http://svn.apache.org/viewvc?view=revision&revision=1455630)

Comment 12 Leonid Zhaldybin 2013-06-18 15:44:16 UTC
Tested on both RHEL5.9 and RHEL6.4 (i386 and x86_64). This issue has been fixed.

Packages used for testing:

RHEL6.4:
python-qpid-0.22-3.el6
python-qpid-qmf-0.22-3.el6
qpid-cpp-client-0.22-4.el6
qpid-cpp-client-devel-0.22-4.el6
qpid-cpp-client-devel-docs-0.22-4.el6
qpid-cpp-server-0.22-4.el6
qpid-cpp-server-devel-0.22-4.el6
qpid-cpp-server-store-0.22-4.el6
qpid-cpp-server-xml-0.22-4.el6
qpid-java-client-0.22-3.el6
qpid-java-common-0.22-3.el6
qpid-java-example-0.22-3.el6
qpid-jca-0.18-8.el6
qpid-jca-xarecovery-0.18-8.el6
qpid-proton-c-0.4-2.2.el6
qpid-qmf-0.22-3.el6
qpid-tools-0.22-3.el6

RHEL5.9:
python-qpid-0.22-2.el5
python-qpid-qmf-0.22-2.el5
qpid-cpp-client-0.22-4.el5
qpid-cpp-client-devel-0.22-4.el5
qpid-cpp-client-devel-docs-0.22-4.el5
qpid-cpp-client-ssl-0.22-4.el5
qpid-cpp-server-0.22-4.el5
qpid-cpp-server-devel-0.22-4.el5
qpid-cpp-server-ha-0.22-4.el5
qpid-cpp-server-ssl-0.22-4.el5
qpid-cpp-server-store-0.22-4.el5
qpid-cpp-server-xml-0.22-4.el5
qpid-java-client-0.22-2.el5
qpid-java-common-0.22-2.el5
qpid-java-example-0.22-2.el5
qpid-jca-0.18-8.el5
qpid-jca-xarecovery-0.18-8.el5
qpid-proton-c-0.4-2.2.el5
qpid-qmf-0.22-2.el5
qpid-qmf-devel-0.22-2.el5
qpid-tools-0.22-2.el5

-> VERIFIED

Comment 13 errata-xmlrpc 2014-09-24 15:06:29 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHEA-2014-1296.html


Note You need to log in before you can comment on or make changes to this bug.