On 2 March 2017 at 13:34, Robbie Gemmell <[email protected]> wrote:
> On 2 March 2017 at 12:06, Rob Godfrey <[email protected]> wrote: > > On 2 March 2017 at 12:56, Robbie Gemmell <[email protected]> > wrote: > > > >> On 1 March 2017 at 18:28, Gordon Sim <[email protected]> wrote: > >> > On 01/03/17 18:14, Rob Godfrey wrote: > >> >> > >> >> The link credit is an absolute value on the wire... but proton > presents > >> it > >> >> in relative terms. If you had 500 units of credit outstanding and > >> >> flow(-500) and then flow(2), and you get 5 messages on the wire > arriving > >> >> after that point... what state is your link credit in in Proton? > >> > > >> > > >> > I would expect it to be 0. > >> > > >> >> Does it > >> >> make a difference if those 5 messages had been processed by Proton > (but > >> >> not > >> >> received by the application) before the flow(2) was sent or not? > >> > > >> > > >> > Yes, if the flow(2) was issued after the 5 messages were processed, I > >> would > >> > expect the credit to be 2. > >> > > >> > >> I think we need to be clearer what we mean by 'in proton' when > >> discussing this - at the application level, or the transport/wire > >> level, and before or after the application processes received > >> messages, as these are all potentially in different states / > >> presenting different views/values for credit at a given time. Indeed > >> doing any of this inside e.g the container/reactor will often give a > >> different result than it would in e.g the JMS client, since the > >> effects of operations will actually occur at different times. > >> > >> I'm not sure most of them will currently match your expectations, > >> credit will actually end up negative in a lot of them. Note in your > >> example, when the timer refreshed credit by doing flow(100) the link > >> credit on the wire actually went to 74, because 3 messages were > >> received/buffered and processed at the receiver before it actually > >> sent the flow reducing credit to 0, then 26 in flight were processed > >> after, making credit end up at -26 once they were all processed, > >> giving an effective 74 later when the flow(100) occurred to 'add 100' > >> credits. > >> > >> Ignore proton for a minute and consider the following at a protocol > >> level. If as a sender you get a flow saying delivery-count is 0 and > >> credit is 100, and send 50 messages in-flight, then get a flow > >> indicating delivery-count is 10 and credit is 0, then receive a flow > >> indicating delivery-count is 20 and credit is 10, what is your actual > >> credit at the sender and receiver when all is done? > > > > > > > > So at this point I would say that the sender considers credit to be 0 > > (there's no point in the sender trying to store a negative link-credit > > amount), at the receiver the link credit is (the most recent > delivery-count > > it saw from the sender) - 30 (this value may be negative). > > > > The spec seems to say it MUST go negative at the sender. From > http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core- > transport-v1.0-os.html#doc-flow-control > on link credit: > > "The sender's value MUST always be maintained in such a way as to > match the delivery-limit identified by the receiver. This means that > the sender's link-credit variable MUST be set according to this > formula when flow information is given by the receiver: > > link-creditsnd := delivery-countrcv + link-creditrcv - delivery-countsnd. " > > So in this case the the receivers last known delivery count was 20, > and the credit was 10, and the senders delivery count was already 50 > at that point. This makes the senders credit -20 (not -30 as I > incorrectly stated below because I cant count, and the sender > delivery-count was only 20 beyond what it could ever become based on > the flow). > > So the sender sees -20 credit as soon as the flow arrives saying 10, > and the receiver ends up seeing -20 once it sees(/processes) all the > messages. > > Theoretically this may be correct, however obviously the credit value on the wire is a uint, so it can't actually be negative. If the receiver has sent a flow with echo=true then I would expect the sender to respond with a flow with the accurate delivery count and a link-credit of 0. Given that the effect of -ve credit and zero credit would seem to be identical I don't think it really matters what the sender stores internally ... though using 0 would allow the library to store the credit value in a uint and not have to futz with the stored value every time it echoes the flow state on the wire. -- Rob > > >> The receivers last > >> flow had just said credit is 10, but the senders delivery-count is > >> already 30 beyond what it could ever become based on that flow, so > >> credit should actually be -30 at the sender now. The receiver also > >> doesn't just end up at 0 after getting 10 more messages based on its > >> last flow, and instead has to cope (or fall over and close the link) > >> when an additional 20 more messages arrive than it seemingly just gave > >> credit for; despite having previously reduced credit from 100 to 0 and > >> increasing it back to 10 after receiving 20 messages, 30 more messages > >> arrived since it never found out if the reduction to 0 took effect and > >> it turns out that 50 (or even up to 100) were sent using the original > >> credit before it adjusted the credit twice more. Suppose we say that > >> the receiver actually successfully processes all 50 messages despite > >> that, this makes its delivery-count now 50 as well, what is its > >> credit? > >> > >> > > I think here there are two separate considerations... On the wire I would > > think that the receiver should update its delivery count to reflect the > > last received delivery from the sender (unless it just decides to tear > down > > the link), and I would expect that the link-credit at this point would be > > zero. > > That would be fine I think, though it doenst currently do this, and to > your point below it would be interesting when to if it did. Currently > at the application level, it doesnt see credit go negative until it > processes enough messages to make it do so, with unprocessed messages > being 'queued' and not yet reflected in credit views. The transport > level does I think consider the credit reduced as soon as they fully > arrive. > > > > > More interesting to me is how we handle this in the interaction between > the > > library and application layers. Does the application layer have to issue > > more credit before the library presents the deliveries to it (even though > > the library is already holding the deliveries). If not then does the > > application layer have to issue retrospective credits in order to start > > receiving new messages? > > > > I'm not sure the accounting part is hard... it's getting the API right > that > > seems more tricky to me. > > > > -- Rob > > > > > >> > >> > > >> > --------------------------------------------------------------------- > >> > To unsubscribe, e-mail: [email protected] > >> > For additional commands, e-mail: [email protected] > >> > > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [email protected] > >> For additional commands, e-mail: [email protected] > >> > >> > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >
