Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Won't Fix
-
0.14
Description
We currently calculate credit replenishment at the session level completely ignoring the capacity of each individual subscription. Further more as per QPID-3612 the completions are tied to message-acks further complicating the issue.
The general formula used for calculating the replenishment rate is as follows.
if (unackedCount >= prefetch/2 || maxAckDelay <= 0 || _acknowledgeMode == javax.jms.Session.AUTO_ACKNOWLEDGE)
{
flushAcknowledgments();
}
There are several issues with this.
1. If the application doesn't ack (in CLIENT_ACK) or commit a transaction before it exhaust the credits, the consumer will starve. See QPID-3612. A recent change done in rev 1195213 fixes the TX case.
2. Ineffective flow control as the calculation happens globally at the session level instead at the subscription level. Due to this, slow consumers can affect fast consumers.
Ex . Assume there are two fast consumers and a slow consumer each with an individual capacity of 20 and the max_prefetch for the connection to be 100. The threshold for sending acks (and therefore completions) is 50. If the fast consumers have already done with their 20 messages, they will have to wait for the slow consumer to do atleast 10 messages before the threshold is hit.