On 2 March 2017 at 13:59, Rob Godfrey <[email protected]> wrote: > 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.
True, I was meaning the effective/stored/calculated value, not the wire value...much like the spec talks of it being less than zero when as you note it never can be on the wire. > 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. In the scenario I wasnt meaning for the 0 credit flow to have an echo, since we cant do that currently, and thats why it didnt wait for the sender to hit 0 credit before sending the next flow, in part to show/put it in position where I see issue with how this would currently behave. If it did support echo, I'm not sure it would reply with credit of 0 currently. > 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. I agree. Proton doesn't look to take either approach currently however. > > -- 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] >> >> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
