diff --git a/index.bs b/index.bs index d5a97d7..aac3805 100644 --- a/index.bs +++ b/index.bs @@ -620,6 +620,7 @@ interface WebTransport { optional WebTransportSendStreamOptions options = {}); /* a ReadableStream of WebTransportReceiveStream objects */ readonly attribute ReadableStream incomingUnidirectionalStreams; + WebTransportSender createSender(); }; enum WebTransportReliabilityMode { @@ -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. @@ -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|. @@ -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. @@ -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|. +: createSender() + +:: 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}
@@ -1287,12 +1303,17 @@ dictionary of parameters that affect how {{WebTransportSendStream}}s created by
 dictionary WebTransportSendStreamOptions {
-  long long? sendOrder = null;
+  WebTransportSender? sender = null;
+  long long sendOrder = 0;
 };
 
The dictionary SHALL have the following attributes: +: sender +:: An optional {{WebTransportSender}} to [=group=] this + {{WebTransportSendStream}} under, or null. + : sendOrder :: An send order number that, if provided, opts the created {{WebTransportSendStream}} in to participating in strict ordering. @@ -1420,7 +1441,8 @@ data to the server.
 [Exposed=(Window,Worker), SecureContext, Transferable]
 interface WebTransportSendStream : WritableStream {
-  attribute long long? sendOrder;
+  attribute WebTransportSender? sender;
+  attribute long long sendOrder;
   Promise<WebTransportSendStreamStats> getStats();
 };
 
@@ -1434,6 +1456,16 @@ The {{WebTransportSendStream}}'s [=transfer steps=] and ## Attributes ## {#send-stream-attributes} +: sender +:: 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|. + : sendOrder :: The getter steps are: 1. Return [=this=]'s {{WebTransportSendStream/[[SendOrder]]}}. @@ -1482,9 +1514,13 @@ A {{WebTransportSendStream}} has the following internal slots. `[[Transport]]` A {{WebTransport}} which owns this {{WebTransportSendStream}}. + + `[[Sender]]` + An optional {{WebTransportSender}}, or null. + `[[SendOrder]]` - An optional send order number, or null. + An optional send order number, defaulting to 0. @@ -1495,7 +1531,8 @@ A {{WebTransportSendStream}} has the following internal slots. To create 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]]}} @@ -1504,6 +1541,8 @@ To create a :: null : {{WebTransportSendStream/[[Transport]]}} :: |transport| + : {{WebTransportSendStream/[[Sender]]}} + :: |sender| : {{WebTransportSendStream/[[SendOrder]]}} :: |sendOrder| 1. Let |writeAlgorithm| be an action that [=writes=] |chunk| to |stream|, given |chunk|. @@ -1539,15 +1578,15 @@ To write |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=]. @@ -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 grouped under at most one +{{WebTransportSender}} at any time. By default, they are +ungrouped. + +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. + +
+[Exposed=(Window,Worker), SecureContext]
+interface WebTransportSender {
+  Promise<WebTransportSendStreamStats> getStats();
+};
+
+ +A {{WebTransportSender}} is always created by the +[=WebTransportSender/create=] procedure. + +## Methods ## {#sender-methods} + +: getStats() +:: Aggregates stats from all {{WebTransportSendStream}}s + [=associated=] with [=this=] sender, and reports the result + asynchronously.

+ + 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|. + 1. Wait for the stats to be ready. + 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. + + + + + + + + + + +
Internal Slot + Description (non-normative) +
`[[Transport]]` + The {{WebTransport}} object owning this {{WebTransportSender}}. +
+ +## Procedures ## {#sender-procedures} + +
+ +To create a +{{WebTransportSender}}, with a {{WebTransport}} |transport|, run these steps: + +1. Let |sender| be a [=new=] {{WebTransportSender}}, with: + : {{WebTransportSender/[[Transport]]}} + :: |transport| +1. Return |sender|. + +
+ + # Interface `WebTransportReceiveStream` # {#receive-stream} A {{WebTransportReceiveStream}} is a {{ReadableStream}} providing incoming streaming