Re: DataChannel API and onopen

On 4/23/2012 4:14 PM, Michael Tuexen wrote:
> On Apr 23, 2012, at 6:22 PM, Tim Panton wrote:
>
>> On 23 Apr 2012, at 17:01, Randell Jesup wrote:
>>
>>> In going over the details for the DataChannel minor protocol and how it works over SCTP, we realized we'll need a 3-way handshake instead of a 2-way.  The reason is that an OPEN_RESPONSE sent ordered followed by a data message sent unordered would allow the data message to come in at the other end before the open response, and since we don't know the input-stream ->  output-stream mapping until we get the OPEN_RESPONSE, we might not know what to do with it.  So we plan to add an ACK message to the protocol to provide the 3-way handshake.
>>>
>> ....
>>
>>> It seems to me that forcing in-order delivery until the handshake is complete is simpler for the user, and only rarely has any impact on the application.  The exception might be if you wanted to dump a bunch of sends that were reliable and out-of-order immediately on creation of the channel - and I don't see it being a major issue there - and you can still wait on onopen if you want.
>>>
>>> Recap: #2 is slightly closer to how WebSockets works (though anything coded for WebSockets' onopen behavior would still work in #1), and #2 avoids potential additional buffering in the stack if the OPEN/OPEN_RESPONSE is lost.  (If it's not lost, there's really no extra buffering occurring, except maybe in the rare case where we need to increase the maximum number of simultaneous streams.)
>>>
>>> Opinions?
>>
>> Is there any way that the handshake can fail ? If there is, then the apis are significantly different in the way that they report that failure.
>> (Since you don't mention a matching NACK I guess this isn't an issue).
> There is a small chance that the handshake can fail. Mainly due to a shortage of resources (streams)...

I should note that if you don't have enough streams, we (will) 
renegotiate for more streams.  We *shouldn't* run out unless there will 
be more than 65536 simultaneous streams in use.

And if it fails, we'll fire onerror and the new data channel will move 
to the closed state without ever firing onopen.

The only reasonable error path that one could use a NACK for currently 
would be closing of the opener's side before it gets open_response, and 
I think that can be dealt with with proper handling of the stream states 
- and for that, I think I'd send the ACK and follow it with the 
(delayed) close/stream-reset.  This actually would be the case I showed: 
createDataChannel(), send(); close().

>> A downside of #2 is we need to define what order data gets sent in this case:
>>
>>    temp = peer.createDataChannel(..)
>>    temp.data_to_send = "I want to send a magic hello string";
>>    temp.onopen = function() {
>>         temp.send(temp.data_to_send);
>>         };
>>   temp.send("I want to send normal activity");
>>   temp.close();
>>   temp = null;
>>

I don't see that we need to specify an order for that case -- though in 
fact we probably could, "normal activity" would be sent first since 
there's no stable state before that send(), and since we close() the 
channel before a stable state, if/when onopen fires later it would fail 
to send anything.  We could hold a reference to the channel until the 
open is finished handshakes and we close(), or we could (more likely) 
release the JS object such that onopen would never fire; I'm open on that.

If you get rid of the close() and temp = null, then the question is 
relevant, but I'd answer the same way with the addition that the onopen 
would be able to send() and it should occur after "normal activity".  If 
"normal activity" is triggered by something else (and not in-line with 
the create), then the ordering would be undefined.

-- 
Randell Jesup
randell-ietf@jesup.org

Received on Monday, 23 April 2012 21:27:06 UTC