On 07/08/2015 03:49 PM, Rafael Schloming wrote:
I think what is confusing about the spec language is that it is defining
the meaning of the value in terms of the sending endpoint's state and then
not saying anything about when the sending endpoint is obligated to
communicate the value to the receiver. This is because (at least as
originally conceived) it is never directly obligated to communicate the
value to the receiver, i.e. it could just choose to grow its array
indefinitely.

By contrast the incoming-window is defined in terms of the receiver's
endpoint state and it is (relatively) clearly communicated that the
receiver is obligated to communicate a non-zero incoming-window if it
wishes to receive transfer frames.

So while I agree that the language as defined requires the outgoing window
to be increased from zero, I don't think this implies (at least without a
more careful reading) that the sender needs to communicate this fact before
sending transfers. It owns the value so it can effectively increase the
outgoing-window to 1 momentarily, send the transfer, and then decrease it
back to zero without needing to sandwich that transfer in flow frames in
order to signal the changing window values.

I think that is a bit of a stretch given the language the spec does use. I agree it doesn't explicitly state the rule in those terms, however it does say:

    The remote-outgoing-window reflects the maximum number of
    incoming transfers that MAY arrive without exceeding the
    remote endpoint’s outgoing-window. This value MUST be
    decremented after every incoming transfer frame is received,
    and recomputed when informed of the remote session endpoint
    state.

I.e. the language suggests that a compliant receiver must do some work to keep track of the value and states that this value is tied to the maximum number of transfers that may arrive.

Put another way, the rule that says it is illegal for the sender to send
transfers when the receiver's incoming window is zero creates an obligation
for the receiver to communicate its window, but there is no corresponding
rule for the receiver, e.g. nothing says it is illegal for the receiver to
send credit when the sender's outgoing-window is zero, nor that the
receiver must compute it's incoming-window based on the sender's
outgoing-window,

I certainly agree that nothing ties the receivers incoming window to the senders outgoing window in any fixed way.

so there is no obligation similarly implied for the sender.

I disagree here. I think the fact that begin and flow have the outgoing-window field defined as mandatory, and the fact that there is specific (though bewildering) language that appears to mandate the tracking of the senders outgoing window by the receiver, *implies* (though does not explicitly spell out) that the sender is supposed to keep the receiver informed of its outgoing window.

Further I think the sender should not take the lack of credit as grounds
to set a window of 0. The receiver knows it has not issued credit. (At the
link level, the sender can also indicate that it has messages awaiting link
credit).


I agree that we shouldn't do this in our implementation, however I think it
is a valid interpretation,

The flow frame describes the outgoing window field as defining:

    the maximum number of outgoing transfer frames that the
    endpoint could potentially currently send, if it was not
    constrained by restrictions imposed by its peer’s
    incoming-window.

To me that explicitly states that the value of the senders outgoing window is not tied to the value of the receivers incoming window, i.e. that a value of 0 for the senders outgoing window cannot reasonably be interpreted as an expectation for the receiver to open its incoming window.

I don't see a single sentence that would tie the session outgoing window to link level credit, which is an entirely distinct mechanism.

The one thing the spec does say of the remote-outgoing-window is that "settling outstanding transfers can cause the window to grow". Settling deliveries frees the sender from needing to track them which clearly *might* enable a constrained sender to then send some more. Likewise a received outcome might allow the sender to make room for further transfers (though this isn't stated anywhere I can see it would seem a reasonable interpretation).

which implies that making the incoming window
dependent on your peers outgoing window (as service-bus is doing) is
probably not a safe thing to do.

Tying the incoming window to the peers outgoing window can only make sense if the sender is expected to keep the receiver up to date with regards to the value of the outgoing window. If that is not the case, then I can't see that the receiver can deduce anything from the outgoing window except that possibly a value of 0 may be a hint that the sender is held up pending some undefined action on the receiver part.

Even if the sender was required to keep the receiver informed of the outgoing window, having the receivers incoming window set to the outgoing window of the sender is not terribly sensible in my view unless the receiver would exapnd its incoming window if/when the sender expanded its outgoing window. But doing that would essentially negate the whole purpose of flow control anyway (i.e. a means for the receiver to protect itself from excessive incoming traffic).

In the case where the sender's implementation involves a fixed amount of
buffer space and requires messages to be settled before it can send more,
the receiver would not be able to know that without getting some signal. So
to my mind that is the only case for which it would make sense to send an
outgoing window of 0. (I'm not sure how useful this is in practice and I
don't believe it applies to proton at present anyway).

I think as it stands proton is violating the spec, and should be changed
to send a non-zero outgoing window.


Per above I don't believe it is violating the spec, but given that it has
been misinterpreted at least once, I certainly agree that some behavior
change is warranted. I don't think we should do the max-frame-size thing
though as this encourages the notion that the incoming-window is somehow
dependent on the outgoing-window which as I said above is I think unsafe.

I guess setting it to a large constant for now is fairly reasonable, but I
do think we should encourage service-bus to make its implementation more
robust in this regard.

Under your interpretation - i.e. where the sender can change the value of the outgoing window without ever having to inform the receiver - the outgoing window seems to have very little value except as a hint that the sender may be constrained by capacity limits on the number of deliveries/transfers it is tracking. To send an outgoing window of 0 when there have not yet even been any transfers seems to undermine even that limited value.

If there is no required behaviour actually specified, and the intention was to use the outgoing window as a hint of constraints on the sender then sending 0 is the worst possible choice. Whatever the value, it is not something the peer can rely on in anyway and using 0 when there are no constraints seems to ignore even the apparent intent.

So yes, my advice to service-bus and anyone else would be to ignore the value. I think the question then is simply what is the least dangerous way to set the mandated field for an implementation that wishes to avoid interop problems. I think some very large fixed window is the best bet. (I'm not sure I understand what the 'max-frame-size thing' is).



Reply via email to