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

Add SendGroup, and make sendOrder no longer nullable. #548

Merged
merged 6 commits into from
Oct 11, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 132 additions & 12 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ interface WebTransport {
optional WebTransportSendStreamOptions options = {});
/* a ReadableStream of WebTransportReceiveStream objects */
readonly attribute ReadableStream incomingUnidirectionalStreams;
WebTransportSender createSender();
};

enum WebTransportReliabilityMode {
Expand Down Expand Up @@ -1001,6 +1002,8 @@ these steps.
1. Let |transport| be [=this=].
1. If |transport|.{{[[State]]}} is `"closed"` or `"failed"`,
return a new [=rejected=] promise with an {{InvalidStateError}}.
1. Let |sender| be {{WebTransport/createBidirectionalStream(options)/options}}'s
{{WebTransportSendStreamOptions/sender}}.
1. Let |sendOrder| be {{WebTransport/createBidirectionalStream(options)/options}}'s
{{WebTransportSendStreamOptions/sendOrder}}.
1. Let |p| be a new promise.
Expand All @@ -1015,7 +1018,7 @@ these steps.
1. If |transport|.{{[[State]]}} is `"closed"` or `"failed"`,
[=reject=] |p| with an {{InvalidStateError}} and abort these steps.
1. Let |stream| be the result of [=BidirectionalStream/creating=] a
{{WebTransportBidirectionalStream}} with |internalStream|, |transport|, and |sendOrder|.
{{WebTransportBidirectionalStream}} with |internalStream|, |transport|, |sender|, and |sendOrder|.
1. [=Resolve=] |p| with |stream|.
1. Return |p|.

Expand All @@ -1030,6 +1033,8 @@ these steps.
1. Let |transport| be [=this=].
1. If |transport|.{{[[State]]}} is `"closed"` or `"failed"`,
return a new [=rejected=] promise with an {{InvalidStateError}}.
1. Let |sender| be {{WebTransport/createUnidirectionalStream(options)/options}}'s
{{WebTransportSendStreamOptions/sender}}.
1. Let |sendOrder| be {{WebTransport/createUnidirectionalStream(options)/options}}'s
{{WebTransportSendStreamOptions/sendOrder}}.
1. Let |p| be a new promise.
Expand All @@ -1044,10 +1049,21 @@ these steps.
1. If |transport|.{{[[State]]}} is `"closed"` or `"failed"`,
[=reject=] |p| with an {{InvalidStateError}} and abort these steps.
1. Let |stream| be the result of [=WebTransportSendStream/creating=] a {{WebTransportSendStream}} with
|internalStream|, |transport|, and |sendOrder|.
|internalStream|, |transport|, |sender|, and |sendOrder|.
1. [=Resolve=] |p| with |stream|.
1. return |p|.

: <dfn for="WebTransport" method>createSender()</dfn>

:: Creates a {{WebTransportSender}}.

When `createSender()` method is called, the user agent MUST
run the following steps:
1. Let |transport| be [=this=].
1. If |transport|.{{[[State]]}} is `"closed"` or `"failed"`,
[=throw=] an {{InvalidStateError}}.
1. Return the result of [=WebTransportSender/creating=] a {{WebTransportSender}} with |transport|.

## Procedures ## {#webtransport-procedures}

<div algorithm="cleanup a WebTransport">
Expand Down Expand Up @@ -1287,12 +1303,17 @@ dictionary of parameters that affect how {{WebTransportSendStream}}s created by

<pre class="idl">
dictionary WebTransportSendStreamOptions {
long long? sendOrder = null;
WebTransportSender? sender = null;
long long sendOrder = 0;
};
</pre>

The dictionary SHALL have the following attributes:

: <dfn for="WebTransportSendStreamOptions" dict-member>sender</dfn>
:: An optional {{WebTransportSender}} to [=group=] this
{{WebTransportSendStream}} under, or null.

: <dfn for="WebTransportSendStreamOptions" dict-member>sendOrder</dfn>
:: An send order number that, if provided, opts the created
{{WebTransportSendStream}} in to participating in <dfn>strict ordering</dfn>.
Expand Down Expand Up @@ -1420,7 +1441,8 @@ data to the server.
<pre class="idl">
[Exposed=(Window,Worker), SecureContext, Transferable]
interface WebTransportSendStream : WritableStream {
attribute long long? sendOrder;
attribute WebTransportSender? sender;
attribute long long sendOrder;
Promise&lt;WebTransportSendStreamStats&gt; getStats();
};
</pre>
Expand All @@ -1434,6 +1456,16 @@ The {{WebTransportSendStream}}'s [=transfer steps=] and

## Attributes ## {#send-stream-attributes}

: <dfn for="WebTransportSendStream" attribute>sender</dfn>
:: The getter steps are:
1. Return [=this=]'s {{WebTransportSendStream/[[Sender]]}}.
:: The setter steps, given |value|, are:
1. If |value| is non-null, and
|value|.{{WebTransportSender/[[Transport]]}} is not
[=this=].{{WebTransportSendStream/[[Transport]]}}, [=throw=]
an {{InvalidStateError}}.
1. Set [=this=].{{WebTransportSendStream/[[Sender]]}} to |value|.

: <dfn for="WebTransportSendStream" attribute>sendOrder</dfn>
:: The getter steps are:
1. Return [=this=]'s {{WebTransportSendStream/[[SendOrder]]}}.
Expand Down Expand Up @@ -1482,9 +1514,13 @@ A {{WebTransportSendStream}} has the following internal slots.
<td><dfn>`[[Transport]]`</dfn>
<td class="non-normative">A {{WebTransport}} which owns this {{WebTransportSendStream}}.
</tr>
<tr>
<td><dfn>`[[Sender]]`</dfn>
<td class="non-normative">An optional {{WebTransportSender}}, or null.
</tr>
<tr>
<td><dfn>`[[SendOrder]]`</dfn>
<td class="non-normative">An optional send order number, or null.
<td class="non-normative">An optional send order number, defaulting to 0.
jan-ivar marked this conversation as resolved.
Show resolved Hide resolved
</tr>
<tbody>
</table>
Expand All @@ -1495,7 +1531,8 @@ A {{WebTransportSendStream}} has the following internal slots.

To <dfn export for="WebTransportSendStream" lt="create|creating">create</dfn> a
{{WebTransportSendStream}}, with an [=outgoing unidirectional=] or [=bidirectional=] [=WebTransport stream=]
|internalStream|, a {{WebTransport}} |transport|, and a |sendOrder|, run these steps:
|internalStream|, a {{WebTransport}} |transport|, |sender|, and a
|sendOrder|, run these steps:

1. Let |stream| be a [=new=] {{WebTransportSendStream}}, with:
: {{WebTransportSendStream/[[InternalStream]]}}
Expand All @@ -1504,6 +1541,8 @@ To <dfn export for="WebTransportSendStream" lt="create|creating">create</dfn> a
:: null
: {{WebTransportSendStream/[[Transport]]}}
:: |transport|
: {{WebTransportSendStream/[[Sender]]}}
:: |sender|
: {{WebTransportSendStream/[[SendOrder]]}}
:: |sendOrder|
1. Let |writeAlgorithm| be an action that [=writes=] |chunk| to |stream|, given |chunk|.
Expand Down Expand Up @@ -1539,15 +1578,15 @@ To <dfn for="WebTransportSendStream">write</dfn> |chunk| to a {{WebTransportSend
This sending MAY be interleaved with sending of previously queued streams and datagrams,
as well as streams and datagrams yet to be queued to be sent over this transport.

If |stream|.{{[[SendOrder]]}} is `null` then this sending MUST NOT starve
except for [=flow control=] reasons or [=WritableStream/Error | error=].

If |stream|.{{[[SendOrder]]}} is not `null` then this sending MUST starve
until all bytes queued for sending on {{WebTransportSendStream}}s with a
non-null and higher {{[[SendOrder]]}}, that are neither
This sending MUST starve
until all bytes queued for sending on {{WebTransportSendStream}}s with the
same {{[[Sender]]}} and a higher {{[[SendOrder]]}}, that are neither
[=WritableStream/Error | errored=] nor blocked by [=flow control=], have been
sent.

This sending MUST NOT starve otherwise,
except for [=flow control=] reasons or [=WritableStream/Error | error=].

The user agent SHOULD divide bandwidth fairly between all streams that aren't starved.

Note: The definition of fairness here is [=implementation-defined=].
Expand Down Expand Up @@ -1677,6 +1716,87 @@ The dictionary SHALL have the following attributes:
Note: This value will match {{WebTransportSendStreamStats/bytesSent}} when
the connection is over HTTP/2.

# Interface `WebTransportSender` # {#sender}

A {{WebTransportSender}} is an optional organizational object that tracks
transmission of data spread across many individual
(typically [=strict ordering|strictly ordered=])
{{WebTransportSendStream}}s.

{{WebTransportSendStream}}s can, at their creation or through assignment of
their `sender` attribute, be <dfn>grouped</dfn> under at most one
{{WebTransportSender}} at any time. By default, they are
<dfn>ungrouped</dfn>.

The user agent considers {{WebTransportSender}}s as equals when allocating
bandwidth for sending {{WebTransportSendStream}}s. Each {{WebTransportSender}}
also establishes a separate numberspace for evaluating
{{WebTransportSendStreamOptions/sendOrder}} numbers.

<pre class="idl">
[Exposed=(Window,Worker), SecureContext]
interface WebTransportSender {
Promise&lt;WebTransportSendStreamStats&gt; getStats();
};
</pre>

A {{WebTransportSender}} is always created by the
[=WebTransportSender/create=] procedure.

## Methods ## {#sender-methods}

: <dfn for="WebTransportSender" method>getStats()</dfn>
:: Aggregates stats from all {{WebTransportSendStream}}s
[=associated=] with [=this=] sender, and reports the result
asynchronously.</p>

When getStats is called, the user agent MUST run the following steps:
1. Let |p| be a new promise.
1. Let |streams| be all {{WebTransportSendStream}}s whose
{{WebTransportSendStream/[[Sender]]}} is [=this=].
1. Run the following steps [=in parallel=]:
1. Gather stats from all |streams|.
jan-ivar marked this conversation as resolved.
Show resolved Hide resolved
1. Wait for the stats to be ready.
jan-ivar marked this conversation as resolved.
Show resolved Hide resolved
1. [=Queue a network task=] with |transport| to run the following steps:
1. Let |stats| be a [=new=] {{WebTransportSendStreamStats}} object
representing the aggregate numbers of the gathered stats.
1. [=Resolve=] |p| with |stats|.
1. Return |p|.

## Internal Slots ## {#sender-internal-slots}

A {{WebTransportSender}} has the following internal slots.

<table class="data" dfn-for="WebTransportSender" dfn-type="attribute">
<thead>
<tr>
<th>Internal Slot
<th>Description (<em>non-normative</em>)
</tr>
</thead>
<tbody>
<tr>
<td><dfn>`[[Transport]]`</dfn>
<td class="non-normative">The {{WebTransport}} object owning this {{WebTransportSender}}.
</tr>
<tbody>
</table>

## Procedures ## {#sender-procedures}

<div algorithm="create a Sender">

To <dfn export for="WebTransportSender" lt="create|creating">create</dfn> a
{{WebTransportSender}}, with a {{WebTransport}} |transport|, run these steps:

1. Let |sender| be a [=new=] {{WebTransportSender}}, with:
: {{WebTransportSender/[[Transport]]}}
:: |transport|
1. Return |sender|.

</div>


# Interface `WebTransportReceiveStream` # {#receive-stream}

A {{WebTransportReceiveStream}} is a {{ReadableStream}} providing incoming streaming
Expand Down
Loading