Skip to content
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

API design #126

Closed
Jxck opened this issue Jul 7, 2020 · 2 comments
Closed

API design #126

Jxck opened this issue Jul 7, 2020 · 2 comments

Comments

@Jxck
Copy link

Jxck commented Jul 7, 2020

Hi forks.

I have some comment/question/proposal for overview of API design.

unidirectional

Promise<SendStream> createSendStream(optional SendStreamParameters parameters = {});
ReadableStream receiveStreams();

createSendStream() will returns SendStream
then why transport.receiveStreams() doesn't return ReceiveStream ?

  1. For each unidirectional stream received, create a corresponding IncomingStream and insert it into [[ReceivedStreams]].

IIUC, IncomingStream has ReadableStream, so if returns IncomingStream enough for reading.(and ReceiveStream is IncomingStream). And it returns single stream at once.

ReceiveStream receiveStream();

And this API is sync, because this returns uni-stream which already on transport.
But make it async can be cover receiving uni-stream initiated from server in the future.

finally I would be

Promise<SendStream> createSendStream(optional SendStreamParameters parameters = {});
Promise<ReceiveStream> createReceiveStream()

bidirectional

At first, BidirectionalStream includes Outgoing/IncomingStream

interface BidirectionalStream {
};
BidirectionalStream includes OutgoingStream;
BidirectionalStream includes IncomingStream;

But Unidirectional uses Send/ReceiveStream which are includes them.
And if some capability will added to Send/ReceiveStream, should also added to BidirectionalStream. So it should be natural for me to

interface BidirectionalStream {
};
BidirectionalStream includes ReceiveStream;
BidirectionalStream includes SendStream;

And here

interface mixin BidirectionalStreamsTransport {
    Promise<BidirectionalStream> createBidirectionalStream();
    ReadableStream receiveBidirectionalStreams();
};

receiveBidirectionalStreams() means createReceiveStreamOfBidirectionalStream().
So in same reason above, it can return ReceiveStream

interface mixin BidirectionalStreamsTransport {
    Promise<BidirectionalStream> createBidirectionalStream();
    ReceiveStream createReceiveStreamOfBidirectionalStream();
};

And what is the reason for only receive are accepted if server initiate bi-directional stream ?
Client can write to client initiated bi-directional stream will be

interface mixin BidirectionalStreamsTransport {
    Promise<BidirectionalStream> createBidirectionalStream();
    BidirectionalStream receiveBidirectionalStream();
};

And if this returns promise which will resolve when client initiate bi-stream in the future.

interface mixin BidirectionalStreamsTransport {
    Promise<BidirectionalStream> createBidirectionalStream();
    Promise<BidirectionalStream> receiveBidirectionalStream();
};

datagram

interface mixin DatagramTransport {
    readonly attribute unsigned short maxDatagramSize;
    WritableStream sendDatagrams();
    ReadableStream receiveDatagrams();
};

As I mentioned in #54 (comment) send/receive is weird.

#54 (comment) seems fine.

interface mixin DatagramTransport {
    readonly attribute unsigned short maxDatagramSize;
    WritableStream readableDatagrams;
    ReadableStream writableDatagrams;
};
@vasilvv
Copy link
Contributor

vasilvv commented Jul 15, 2020

Regarding the first section:

createSendStream() will returns SendStream
then why transport.receiveStreams() doesn't return ReceiveStream ?

In QUIC (and WebTransport in general), creating and receiving streams is subject to backpressure. Thus, receiveStreams() returns a ReadableStream of ReceiveStream, since ReadableStream is a Web primitive for backpressure. Unfortunately, we couldn't make sendStreams() a WriteableStream of SendStream, since the SendStream object itself has to be created internally, and making sendStreams() a WriteableStream would require the SendStream to be created outside. Thus we settled for a somewhat asymmetric approach that's currently in the draft.

Regarding the second section:

BidirectionalStream includes ReceiveStream;
BidirectionalStream includes SendStream;

This doesn't really work in WebIDL, since includes can only take interface mixins on the right-hand side, and not interfaces themselves. That limitation in WebIDL is why we have the distinction between SendStream/ReceiveStream and IncomingStream/OutgoingStream.

Regarding the third section, I've left the reply in #54.

@jan-ivar
Copy link
Member

This one appears answered. Some calls for symmetry should be covered in #40.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants