-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Large change refactoring unidirectional streams. #70
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I like it :).
index.html
Outdated
attribute EventHandler onstatechange; | ||
attribute EventHandler onerror; | ||
attribute EventHandler onquicstream; | ||
attribute EventHandler onnewreceivestreamwithdata; | ||
attribute EventHandler onnewbidirectionalstreamwithdata; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first I thought "onnewXwithdata" was a weird, but then I realized you're trying to emphasize that this only fires once there is data, and that it's a stream that may get more data.
I can't think of a better naming scheme for it (it seems like the best name anyone has come up with so far). So I'm in favor of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was considering adding a comment about ideas for renaming this. We couldn't think of a better one, but I'm definitely open to other ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are the events delayed until there is data? With data channels, the ondatachannel event isn't delayed until there are messages. Couldn't this disparity cause problems in implementing the RTCDataChannel API on top of this API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably if you were implementing RTCDataChannel on top, you'd have some amount of header in the front of the stream (with something like the data channel ID). That header would be the first data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QUIC doesn't create a receive stream right away because it requires sending a STREAM frame from the send side. Presumably you could get around this by:
- Sending a STREAM frame with 0 data, but currently gquic doesn't allow without including the FIN bit.
- Bidirectional streams support creating a bidirectional stream on the receive side with the receipt of a MAX_STREAM_DATA frame (coming from the receive stream on the send side). I don't think this is supported by gquic, but it might take some digging to know for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The long name also seems awkward to me. I'm wondering why that information needs to be provided as part of the event's name. Is it important that the event only fires when there is data? In addition, is it important to emphasize that it's new?
How about onreceivestream
and onbidirectionalstream
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lgrahl The event will only emit newly created streams, so “new” seems redundant. onreceivestream
and onbirectionalstream
seems more compact to me.
Also, the spirit of converging with WHATWG streams, should we support cancel (reason)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for converging with the Streams API, adding cancel
to the reader and abort
to the writer would be sensible. IIRC, .abortReading
and .abortWriting
would just need to be renamed for that purpose. The Streams API also allows to return a Promise
. This could for example be used to resolve once the closing procedure has been completed.
In my demo code (which is based on bidirectional streams), .abort
and .cancel
trigger an error on both readable/writable controllers which results in exceptions on pending async read/write operations. For unidirectional streams, only the associated stream controller would have to be error-ed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should leave them "abort" until we make a decision about WHATWG streams.
This is similar to what I think of in general for this PR: let's merge it to get the main things in place and then address little things like the names with followup PRs.
interface mixin RTCQuicWritableStream { | ||
readonly attribute boolean writable; | ||
readonly attribute unsigned long writeBufferedAmount; | ||
readonly attribute Promise<RTCQuicStreamAbortInfo> writingAborted; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Promise attribute? I've never seen that before. What are the pros/cons vs. an event handler? Is it so that you can get the promise after it fired (unlike an event which you may miss)? Or is it to emphasize that it will only fire once?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's nice for the reasons you mentioned:
- You can get it after it has fired. If the promise has already been settled, it will still fulfill/reject appropriately.
- Making it an attribute means that there should only be one promise that will only settled once.
- We should only get a callback for a RST_STREAM/STOP_SENDING frame once
Here's a blog post where I learned about promises and explains a tiny amount about when they're more appropriate than events (spoiler alert it's pretty much what you said).
https://developers.google.com/web/fundamentals/primers/promises#events_arent_always_the_best_way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the RTCDataChannel
API, we have the onclose
event that is only used once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't disagree that an event could work here, but a promise seems more appropriate. The WHATWG streams do the same thing:
https://streams.spec.whatwg.org/#default-reader-closed
https://streams.spec.whatwg.org/#default-writer-closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that Promise
s are a useful alternative to fire once events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about I keep this as a Promise in this PR, and we can move this discussion for after it merges if anyone still feels strongly for using an event here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds ok.
Thanks for giving this a look Peter! |
LGTM |
…WritableStreams]] slots, and added steps for removing stream in write() method.
(Having read @aboba's mailing list posting)
At the moment, I'm not sure what kind of feedback you would like to get because, to be honest, due to the lack of reactions I felt largely ignored by this group and mostly stopped my efforts... apart from occasional pinging. The demo and the spec draft of #2 is still there. While the API has been changed since December 2017, it's not that far off and should provide enough insight into how QUIC can be married with streams. I'm there if you have questions and the WHATWG folks that helped me experiment with this can be pinged in freenode's |
Hi @lgrahl. I apologize for not looking more deeply into WHATWG streams your demo & spec draft in your initial issue filing. It's being readdressed if WHATWG streams are the right solution here (especially as the spec moves closer to readable/writable streams) and I'm going to look into it more deeply when I get a chance. I think the best path forward here is to merge this PR first as it is something that has more consensus, and address WHATWG streams next. |
index.html
Outdated
attribute EventHandler onstatechange; | ||
attribute EventHandler onerror; | ||
attribute EventHandler onquicstream; | ||
attribute EventHandler onnewreceivestreamwithdata; | ||
attribute EventHandler onnewbidirectionalstreamwithdata; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should leave them "abort" until we make a decision about WHATWG streams.
This is similar to what I think of in general for this PR: let's merge it to get the main things in place and then address little things like the names with followup PRs.
…m events and added back waitForReadable() to the interface.
Can we merge this? The fact that it hasn't been merged has caused some confusion in pre-TPAC discussions. |
Sounds good to me. @aboba @robin-raymond any objections? |
This is a large change, as discussed in issue 69 & prototyped in this doc.
To view refer to this page:
https://rawgit.com/w3c/webrtc-quic/unidirectional-streams-and-state-update/index.html
I think this is a good starting point. Feel free to make commits to this. My hope is that we can get this change in quickly, then iterate on it with further details/issues.
Issues that can be closed after this PR goes through: