[ 
https://issues.apache.org/jira/browse/QPID-8538?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17360190#comment-17360190
 ] 

Robbie Gemmell commented on QPID-8538:
--------------------------------------

The delta behaviour isnt an incompatibility with the broker, you just dont 
fully understand the mechanism they are doing.

The process of 'draining' the link credit is expected to result in credit 
returning to 0, either from the broker sending enough messages to use all the 
credit, or by the broker sending what it can (nothing in this case) and 
advancing the delivery 'count' (which per the AMQP 1.0 spec itself, isnt a 
count; dont ask me why it wasnt renamed) to burn all remaining credit. This 
draining mechanism is how the fetch call satisfies its API doc that it will 
check the server before saying there are no messages, unlike 'get'. If the 
drain completes and there were no queued messages the client then grants more 
credit. 

The overall behaviour looks to try avoiding pre fetching more than 'capacity' 
messages, which it will...though seems like it will only grant new credit when 
the last message resulting form the drain is consumed, when it could perhaps do 
so earlier in cases (though probably not in the way you suggest since it would 
need to await the drain completing first). I would doubt this behaviour will 
change any time soon given very limited changes being made to qpid-cpp at this 
point.

Note that pn_link_queued operates only around 'messages already known locally 
to proton but yet to be extracted/received from the link object', it knows 
nothing about the remote server.

 

It sounds like you should perhaps look to use the 'get' call generally, which 
only operates locally and would avoid all such 'draining' and related 
behaviour. Or better yet use Proton C++ since that is where all the current 
development is.

> Receiver fetch method depletes credit and slows down receiver
> -------------------------------------------------------------
>
>                 Key: QPID-8538
>                 URL: https://issues.apache.org/jira/browse/QPID-8538
>             Project: Qpid
>          Issue Type: Bug
>          Components: C++ Client
>    Affects Versions: qpid-cpp-1.39.0
>            Reporter: Peter Moran
>            Priority: Major
>
> As remote broker java broker is used.
> e.g 
>  capacity of link is 10
>  credit is 10
> When calling Method ConnectionContext::fetch and there are no data available 
> inside receiver (get returns false) it
>  # Enables drain mode  pn_link_drain(lnk->receiver, 0);
>  # Tries to process all queued messages (while 
> (pn_link_draining(lnk->receiver) && !pn_link_queued(lnk->receiver)))
>  # Credit is being drained by broker pn_do_flow in proton ( pn_sequence_t 
> delta = delivery_count - link->state.delivery_count;) -> delta is 10 and 
> credit is cleared to 0, yet no messages arrived from broker at all
>  if there are queued messages and credit is 0 then pn_link_draining returns 
> false and while stops
>  # however if (lnk->capacity && pn_link_queued(lnk->receiver) == 0) replenish 
> credit only if there are no outstanding queued messages to the maximum 
> capacity, this should be rather capacity - credit, but also the condition 
> seems to be wrong, it should not check the queued messages.
> the code should look like this
> {code:java}
> if (lnk->capacity) {
>     pn_link_flow(lnk->receiver, lnk->capacity - 
> pn_link_credit(lnk->receiver));
> }
> or
> if (lnk->capacity) { 
> pn_link_flow(lnk->receiver, pn_link_drained(lnk->receiver));
> }{code}
> this would much more look like what is inside proton c++ api
> {code:java}
> void credit_topup(pn_link_t *link) {
>     assert(pn_link_is_receiver(link));
>     int window = link_context::get(link).credit_window;
>     if (window) {
>         int delta = window - pn_link_credit(link);
>         pn_link_flow(link, delta);
>     }
> }
>       // receiver
>             if (!pn_link_credit(lnk) && lctx.draining) {
>                 lctx.draining = false;
>                 pn_link_set_drain(lnk, false);
>                 receiver r(make_wrapper<receiver>(lnk));
>                 handler.on_receiver_drain_finish(r);
>             }
>             credit_topup(lnk);
> {code}
> there is no condition about queued and also the resulting credit is set to 
> the link capacity 
>  (e.g 10 - delta) delta is delivery count reduced from by pn_do_flow,
> However this to me looks like some incompatibility between client and broker, 
> as one would not expect that delta is 10 if no messages are received from 
> broker. is this some kind of message sequencing problem?
>  
> fyi pn_link_queued messages does not mean they they are locally available 
> they might be still on broker and also getAvaialable implementation is wrong.
>  
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to