From 7fddf5ecb16ede7e3d2de5a8f39ce3ba4b67cd7e Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Wed, 15 Sep 2021 01:03:13 +0200 Subject: [PATCH 01/13] Add WritableStreamDefaultController.releaseBackpressure() --- .../WritableStreamDefaultController-impl.js | 8 ++++++++ .../WritableStreamDefaultController.webidl | 1 + .../lib/abstract-ops/writable-streams.js | 20 +++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/reference-implementation/lib/WritableStreamDefaultController-impl.js b/reference-implementation/lib/WritableStreamDefaultController-impl.js index 1e4b58a51..d60e226e5 100644 --- a/reference-implementation/lib/WritableStreamDefaultController-impl.js +++ b/reference-implementation/lib/WritableStreamDefaultController-impl.js @@ -21,6 +21,14 @@ exports.implementation = class WritableStreamDefaultControllerImpl { aos.WritableStreamDefaultControllerError(this, e); } + releaseBackpressure() { + const state = this._stream._state; + if (state !== 'writable') { + return; + } + aos.WritableStreamDefaultControllerReleaseBackpressure(this); + } + [AbortSteps](reason) { const result = this._abortAlgorithm(reason); aos.WritableStreamDefaultControllerClearAlgorithms(this); diff --git a/reference-implementation/lib/WritableStreamDefaultController.webidl b/reference-implementation/lib/WritableStreamDefaultController.webidl index 25139e6ff..b08eb71ee 100644 --- a/reference-implementation/lib/WritableStreamDefaultController.webidl +++ b/reference-implementation/lib/WritableStreamDefaultController.webidl @@ -2,4 +2,5 @@ interface WritableStreamDefaultController { readonly attribute AbortSignal signal; undefined error(optional any e); + undefined releaseBackpressure(); }; diff --git a/reference-implementation/lib/abstract-ops/writable-streams.js b/reference-implementation/lib/abstract-ops/writable-streams.js index cf303bfe7..f68b2a21f 100644 --- a/reference-implementation/lib/abstract-ops/writable-streams.js +++ b/reference-implementation/lib/abstract-ops/writable-streams.js @@ -27,6 +27,7 @@ Object.assign(exports, { WritableStreamDefaultControllerClearAlgorithms, WritableStreamDefaultControllerError, WritableStreamDefaultControllerErrorIfNeeded, + WritableStreamDefaultControllerReleaseBackpressure, WritableStreamDefaultWriterAbort, WritableStreamDefaultWriterClose, WritableStreamDefaultWriterCloseWithErrorPropagation, @@ -543,6 +544,7 @@ function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm controller._abortController = new AbortController(); controller._started = false; + controller._releaseBackpressure = false; controller._strategySizeAlgorithm = sizeAlgorithm; controller._strategyHWM = highWaterMark; @@ -657,6 +659,9 @@ function WritableStreamDefaultControllerErrorIfNeeded(controller, error) { } function WritableStreamDefaultControllerGetBackpressure(controller) { + if (controller._releaseBackpressure === true) { + return false; + } const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller); return desiredSize <= 0; } @@ -727,6 +732,19 @@ function WritableStreamDefaultControllerProcessWrite(controller, chunk) { ); } +function WritableStreamDefaultControllerReleaseBackpressure(controller) { + const stream = controller._stream; + assert(stream._state === 'writable'); + + controller._releaseBackpressure = true; + + if (WritableStreamHasOperationMarkedInFlight(stream) === false && + WritableStreamCloseQueuedOrInFlight(stream) === false) { + const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); + WritableStreamUpdateBackpressure(stream, backpressure); + } +} + function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) { try { EnqueueValueWithSize(controller, chunk, chunkSize); @@ -735,6 +753,8 @@ function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) { return; } + controller._releaseBackpressure = false; + const stream = controller._stream; if (WritableStreamCloseQueuedOrInFlight(stream) === false && stream._state === 'writable') { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); From ceaf04e6e7792a5c8e41ca766c9a29113719cc69 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Wed, 24 Nov 2021 21:34:45 +0100 Subject: [PATCH 02/13] Use releaseBackpressure() in TransformStream pull() algorithm --- .../lib/abstract-ops/transform-streams.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/reference-implementation/lib/abstract-ops/transform-streams.js b/reference-implementation/lib/abstract-ops/transform-streams.js index 8e3f5fcc3..eefa08a33 100644 --- a/reference-implementation/lib/abstract-ops/transform-streams.js +++ b/reference-implementation/lib/abstract-ops/transform-streams.js @@ -7,7 +7,8 @@ const { promiseResolvedWith, promiseRejectedWith, newPromise, resolvePromise, tr const { CreateReadableStream, ReadableStreamDefaultControllerClose, ReadableStreamDefaultControllerEnqueue, ReadableStreamDefaultControllerError, ReadableStreamDefaultControllerHasBackpressure, ReadableStreamDefaultControllerCanCloseOrEnqueue } = require('./readable-streams.js'); -const { CreateWritableStream, WritableStreamDefaultControllerErrorIfNeeded } = require('./writable-streams.js'); +const { CreateWritableStream, WritableStreamDefaultControllerErrorIfNeeded, + WritableStreamDefaultControllerReleaseBackpressure } = require('./writable-streams.js'); const TransformStream = require('../../generated/TransformStream.js'); const TransformStreamDefaultController = require('../../generated/TransformStreamDefaultController.js'); @@ -98,6 +99,10 @@ function TransformStreamSetBackpressure(stream, backpressure) { stream._backpressureChangePromise = newPromise(); stream._backpressure = backpressure; + + if (backpressure === false && stream._writable._state === 'writable') { + WritableStreamDefaultControllerReleaseBackpressure(stream._writable._controller); + } } // Default controllers From 7b24e7fe2d34e6a1e1cee1b67c343eeaae740404 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Thu, 25 Nov 2021 01:12:56 +0100 Subject: [PATCH 03/13] Roll WPT --- reference-implementation/web-platform-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-implementation/web-platform-tests b/reference-implementation/web-platform-tests index 99d74f952..a29e04bfe 160000 --- a/reference-implementation/web-platform-tests +++ b/reference-implementation/web-platform-tests @@ -1 +1 @@ -Subproject commit 99d74f9529e16ec0722ef11136ab29b9e80fff26 +Subproject commit a29e04bfee68ff88267e3ac4258a7bf2dac119f6 From 265c346c2f9c5d8fd9f83ee1c030724b25554ba4 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 00:47:48 +0100 Subject: [PATCH 04/13] Ignore releaseBackpressure() if there are queued chunks --- reference-implementation/lib/abstract-ops/writable-streams.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-implementation/lib/abstract-ops/writable-streams.js b/reference-implementation/lib/abstract-ops/writable-streams.js index f68b2a21f..1e3c91a52 100644 --- a/reference-implementation/lib/abstract-ops/writable-streams.js +++ b/reference-implementation/lib/abstract-ops/writable-streams.js @@ -659,7 +659,7 @@ function WritableStreamDefaultControllerErrorIfNeeded(controller, error) { } function WritableStreamDefaultControllerGetBackpressure(controller) { - if (controller._releaseBackpressure === true) { + if (controller._releaseBackpressure === true && controller._queue.length === 0) { return false; } const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller); From 90b00cb666d4209b827eaf92e93f5604dc4c2861 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 15:39:14 +0100 Subject: [PATCH 05/13] Roll WPT --- reference-implementation/web-platform-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-implementation/web-platform-tests b/reference-implementation/web-platform-tests index a29e04bfe..d36b53068 160000 --- a/reference-implementation/web-platform-tests +++ b/reference-implementation/web-platform-tests @@ -1 +1 @@ -Subproject commit a29e04bfee68ff88267e3ac4258a7bf2dac119f6 +Subproject commit d36b530682dde83fade0ddea06b1fae676a5c3eb From cf30f6effa969250acd78ff6f5d02d1b2022dd1d Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 16:20:29 +0100 Subject: [PATCH 06/13] Fix "is empty" links in spec text --- index.bs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/index.bs b/index.bs index 692c85fcc..8397c0706 100644 --- a/index.bs +++ b/index.bs @@ -1040,7 +1040,7 @@ default-reader-asynciterator-prototype-internal-slots">Asynchronous iteration 0, 1. Set |controller|.[=ReadableByteStreamController/[[closeRequested]]=] to true. 1. Return. - 1. If |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not empty, + 1. If |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not + [=list/is empty|empty=], 1. Let |firstPendingPullInto| be |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=][0]. 1. If |firstPendingPullInto|'s [=pull-into descriptor/bytes filled=] > 0, @@ -3225,8 +3226,7 @@ The following abstract operations support the implementation of the 1. If ! [$ReadableStreamHasDefaultReader$](|stream|) is true, 1. Perform ! [$ReadableByteStreamControllerProcessReadRequestsUsingQueue$](|controller|). 1. If ! [$ReadableStreamGetNumReadRequests$](|stream|) is 0, - 1. Assert: |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is - [=list/is empty|empty=]. + 1. Assert: |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] [=list/is empty=]. 1. Perform ! [$ReadableByteStreamControllerEnqueueChunkToQueue$](|controller|, |transferredBuffer|, |byteOffset|, |byteLength|). 1. Otherwise, @@ -3504,7 +3504,8 @@ The following abstract operations support the implementation of the |byteLength|, [=pull-into descriptor/bytes filled=] 0, [=pull-into descriptor/element size=] |elementSize|, [=pull-into descriptor/view constructor=] |ctor|, and [=pull-into descriptor/reader type=] "`byob`". - 1. If |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not empty, + 1. If |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not + [=list/is empty|empty=], 1. [=list/Append=] |pullIntoDescriptor| to |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=]. 1. Perform ! [$ReadableStreamAddReadIntoRequest$](|stream|, |readIntoRequest|). @@ -3538,7 +3539,8 @@ The following abstract operations support the implementation of the id="readable-byte-stream-controller-respond">ReadableByteStreamControllerRespond(|controller|, |bytesWritten|) performs the following steps: - 1. Assert: |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not empty. + 1. Assert: |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not + [=list/is empty|empty=]. 1. Let |firstDescriptor| be |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=][0]. 1. Let |state| be |controller|.[=ReadableByteStreamController/[[stream]]=].[=ReadableStream/[[state]]=]. @@ -4881,7 +4883,7 @@ the {{WritableStream}}'s public API. performs the following steps: 1. Assert: |stream|.[=WritableStream/[[inFlightWriteRequest]]=] is undefined. - 1. Assert: |stream|.[=WritableStream/[[writeRequests]]=] is not empty. + 1. Assert: |stream|.[=WritableStream/[[writeRequests]]=] is not [=list/is empty|empty=]. 1. Let |writeRequest| be |stream|.[=WritableStream/[[writeRequests]]=][0]. 1. [=list/Remove=] |writeRequest| from |stream|.[=WritableStream/[[writeRequests]]=]. 1. Set |stream|.[=WritableStream/[[inFlightWriteRequest]]=] to |writeRequest|. @@ -5146,7 +5148,7 @@ The following abstract operations support the implementation of the 1. If |state| is "`erroring`", 1. Perform ! [$WritableStreamFinishErroring$](|stream|). 1. Return. - 1. If |controller|.[=WritableStreamDefaultController/[[queue]]=] is empty, return. + 1. If |controller|.[=WritableStreamDefaultController/[[queue]]=] [=list/is empty=], return. 1. Let |value| be ! [$PeekQueueValue$](|controller|). 1. If |value| is the [=close sentinel=], perform ! [$WritableStreamDefaultControllerProcessClose$](|controller|). @@ -5247,7 +5249,7 @@ The following abstract operations support the implementation of the 1. Let |stream| be |controller|.[=WritableStreamDefaultController/[[stream]]=]. 1. Perform ! [$WritableStreamMarkCloseRequestInFlight$](|stream|). 1. Perform ! [$DequeueValue$](|controller|). - 1. Assert: |controller|.[=WritableStreamDefaultController/[[queue]]=] is empty. + 1. Assert: |controller|.[=WritableStreamDefaultController/[[queue]]=] [=list/is empty=]. 1. Let |sinkClosePromise| be the result of performing |controller|.[=WritableStreamDefaultController/[[closeAlgorithm]]=]. 1. Perform ! [$WritableStreamDefaultControllerClearAlgorithms$](|controller|). From fc0cb9d61118dd43993d7a416c0b9619422492ae Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 18:10:24 +0100 Subject: [PATCH 07/13] Update spec text --- index.bs | 57 +++++++++++++++++-- .../lib/abstract-ops/writable-streams.js | 2 +- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/index.bs b/index.bs index 8397c0706..7cc099a30 100644 --- a/index.bs +++ b/index.bs @@ -4295,11 +4295,12 @@ following table:
await writer.{{WritableStreamDefaultWriter/ready}}
-

Returns a promise that will be fulfilled when the [=desired size to fill a stream's internal - queue|desired size to fill the stream's internal queue=] transitions from non-positive to - positive, signaling that it is no longer applying [=backpressure=]. Once the [=desired size to - fill a stream's internal queue|desired size=] dips back to zero or below, the getter will return - a new promise that stays pending until the next transition. +

Returns a promise that will be fulfilled when either the [=desired size to fill a stream's + internal queue|desired size to fill the stream's internal queue=] transitions from non-positive to + positive or when the stream calls {{WritableStreamDefaultController/releaseBackpressure()}}, + signaling that it is no longer applying [=backpressure=]. + Once the [=desired size to fill a stream's internal queue|desired size=] dips back to zero or below, + the getter will return a new promise that stays pending until the next transition.

If the stream becomes errored or aborted, or the writer's lock is [=release a write lock|released=], the returned promise will become rejected. @@ -4425,6 +4426,7 @@ The Web IDL definition for the {{WritableStreamDefaultController}} class is give interface WritableStreamDefaultController { readonly attribute AbortSignal signal; undefined error(optional any e); + undefined releaseBackpressure(); }; @@ -4454,6 +4456,10 @@ the following table: \[[queueTotalSize]] The total size of all the chunks stored in [=WritableStreamDefaultController/[[queue]]=] (see [[#queue-with-sizes]]) + + \[[releaseBackpressure]] + A boolean flag indicating whether to release backpressure until the + next chunk is written \[[signal]] An {{AbortSignal}} that can be used to abort the pending write or @@ -4500,6 +4506,17 @@ closed. It is only used internally, and is never exposed to web developers. the [=underlying sink=]'s methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the normal lifecycle of interactions with the [=underlying sink=]. +

controller.{{WritableStreamDefaultController/releaseBackpressure()|releaseBackpressure}}() +
+

Releases [=backpressure=] until the next chunk is written. If there are still chunks in the queue, + this does nothing. + +

Usually, backpressure is automatically released when the [=desired size to fill a stream's + internal queue|desired size to fill the stream's internal queue=] becomes positive. However, + if the stream is created with a [=high water mark=] of zero, then the desired size is always at or + below zero, and the stream would always apply backpressure. + This method allows the [=underlying sink=] to manually release backpressure, for example when it + knows that now is a good time for the [=producer=] to write a new chunk.

@@ -4518,6 +4535,15 @@ closed. It is only used internally, and is never exposed to web developers. 1. Perform ! [$WritableStreamDefaultControllerError$]([=this=], |e|).
+
+ The releaseBackpressure() method steps are: + + 1. Let |state| be [=this=].[=WritableStreamDefaultController/[[stream]]=].[=WritableStream/[[state]]=]. + 1. If |state| is not "`writable`", return. + 1. Perform ! [$WritableStreamDefaultControllerReleaseBackpressure$]([=this=]). +
+

Internal methods

The following are internal methods implemented by each {{WritableStreamDefaultController}} instance. @@ -5082,6 +5108,7 @@ The following abstract operations support the implementation of the 1. Set |controller|.[=WritableStreamDefaultController/[[stream]]=] to |stream|. 1. Set |stream|.[=WritableStream/[[controller]]=] to |controller|. 1. Perform ! [$ResetQueue$](|controller|). + 1. Set |controller|.[=WritableStreamDefaultController/[[releaseBackpressure]]=] to false. 1. Set |controller|.[=WritableStreamDefaultController/[[signal]]=] to a new {{AbortSignal}}. 1. Set |controller|.[=WritableStreamDefaultController/[[started]]=] to false. 1. Set |controller|.[=WritableStreamDefaultController/[[strategySizeAlgorithm]]=] to @@ -5213,6 +5240,8 @@ The following abstract operations support the implementation of the id="writable-stream-default-controller-get-backpressure">WritableStreamDefaultControllerGetBackpressure(|controller|) performs the following steps: + 1. If |controller|.[=WritableStreamDefaultController/[[releaseBackpressure]]=] is true and + |controller|.[=WritableStreamDefaultController/[[queue]]=] [=list/is empty=], return false. 1. Let |desiredSize| be ! [$WritableStreamDefaultControllerGetDesiredSize$](|controller|). 1. Return true if |desiredSize| ≤ 0, or false otherwise. @@ -5283,6 +5312,20 @@ The following abstract operations support the implementation of the 1. Perform ! [$WritableStreamFinishInFlightWriteWithError$](|stream|, |reason|). +
+ WritableStreamDefaultControllerReleaseBackpressure(|controller|) + performs the following steps: + + 1. Let |stream| be |controller|.[=WritableStreamDefaultController/[[stream]]=]. + 1. Assert: |stream|.[=WritableStream/[[state]]=] is "`writable`". + 1. Set |controller|.[=WritableStreamDefaultController/[[releaseBackpressure]]=] to true. + 1. If ! [$WritableStreamHasOperationMarkedInFlight$](|stream|) is false and + [$WritableStreamCloseQueuedOrInFlight$](|stream|) is false, + 1. Let |backpressure| be ! [$WritableStreamDefaultControllerGetBackpressure$](|controller|). + 1. Perform ! [$WritableStreamUpdateBackpressure$](|stream|, |backpressure|). +
+
WritableStreamDefaultControllerWrite(|controller|, @@ -5293,6 +5336,7 @@ The following abstract operations support the implementation of the 1. Perform ! [$WritableStreamDefaultControllerErrorIfNeeded$](|controller|, |enqueueResult|.\[[Value]]). 1. Return. + 1. Set |controller|.[=WritableStreamDefaultController/[[releaseBackpressure]]=] to false. 1. Let |stream| be |controller|.[=WritableStreamDefaultController/[[stream]]=]. 1. If ! [$WritableStreamCloseQueuedOrInFlight$](|stream|) is false and |stream|.[=WritableStream/[[state]]=] is "`writable`", @@ -5805,6 +5849,9 @@ The following abstract operations operate on {{TransformStream}} instances at a stream.[=TransformStream/[[backpressureChangePromise]]=] with undefined. 1. Set |stream|.[=TransformStream/[[backpressureChangePromise]]=] to [=a new promise=]. 1. Set |stream|.[=TransformStream/[[backpressure]]=] to |backpressure|. + 1. If |backpressure| is false and |stream|.[=TransformStream/[[writable]]=].[=WritableStream/[[state]]=] + is "`writable`", perform ! + [$WritableStreamDefaultControllerReleaseBackpressure$](|stream|.[=TransformStream/[[writable]]=].[=WritableStream/[[controller]]=]).

Default controllers

diff --git a/reference-implementation/lib/abstract-ops/writable-streams.js b/reference-implementation/lib/abstract-ops/writable-streams.js index 1e3c91a52..8c309139a 100644 --- a/reference-implementation/lib/abstract-ops/writable-streams.js +++ b/reference-implementation/lib/abstract-ops/writable-streams.js @@ -542,9 +542,9 @@ function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm controller._queueTotalSize = undefined; ResetQueue(controller); + controller._releaseBackpressure = false; controller._abortController = new AbortController(); controller._started = false; - controller._releaseBackpressure = false; controller._strategySizeAlgorithm = sizeAlgorithm; controller._strategyHWM = highWaterMark; From 95323e7c901627e3736b204a3d448f5e33d2af4c Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 18:53:18 +0100 Subject: [PATCH 08/13] Reset flag before processing a new chunk --- index.bs | 1 + reference-implementation/lib/abstract-ops/writable-streams.js | 1 + 2 files changed, 2 insertions(+) diff --git a/index.bs b/index.bs index 7cc099a30..83cd8dc48 100644 --- a/index.bs +++ b/index.bs @@ -5295,6 +5295,7 @@ The following abstract operations support the implementation of the 1. Let |stream| be |controller|.[=WritableStreamDefaultController/[[stream]]=]. 1. Perform ! [$WritableStreamMarkFirstWriteRequestInFlight$](|stream|). + 1. Set |controller|.[=WritableStreamDefaultController/[[releaseBackpressure]]=] to false. 1. Let |sinkWritePromise| be the result of performing |controller|.[=WritableStreamDefaultController/[[writeAlgorithm]]=], passing in |chunk|. 1. [=Upon fulfillment=] of |sinkWritePromise|, diff --git a/reference-implementation/lib/abstract-ops/writable-streams.js b/reference-implementation/lib/abstract-ops/writable-streams.js index 8c309139a..7aeb78bc1 100644 --- a/reference-implementation/lib/abstract-ops/writable-streams.js +++ b/reference-implementation/lib/abstract-ops/writable-streams.js @@ -704,6 +704,7 @@ function WritableStreamDefaultControllerProcessWrite(controller, chunk) { const stream = controller._stream; WritableStreamMarkFirstWriteRequestInFlight(stream); + controller._releaseBackpressure = false; const sinkWritePromise = controller._writeAlgorithm(chunk); uponPromise( From 96c8cd19a106a086d2395d7cd41097577a8978d2 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 18:53:28 +0100 Subject: [PATCH 09/13] Roll WPT --- reference-implementation/web-platform-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-implementation/web-platform-tests b/reference-implementation/web-platform-tests index d36b53068..db995f6f8 160000 --- a/reference-implementation/web-platform-tests +++ b/reference-implementation/web-platform-tests @@ -1 +1 @@ -Subproject commit d36b530682dde83fade0ddea06b1fae676a5c3eb +Subproject commit db995f6f8b4d236444ad67fa525ce4237cdf3f2f From ad8891636cf67280483cfb6ce169fe287c3fdacd Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 23:40:30 +0100 Subject: [PATCH 10/13] Add HWM and size algorithms to "set up a TransformStream" --- index.bs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/index.bs b/index.bs index 83cd8dc48..d32921b2a 100644 --- a/index.bs +++ b/index.bs @@ -6953,7 +6953,7 @@ for="ReadableStream">locked if ! [$IsReadableStreamLocked$](|stream|) retu up">writeAlgorithm, an optional algorithm closeAlgorithm, an optional algorithm abortAlgorithm, an optional number highWaterMark (default 1), an optional algorithm highWaterMark (default 1), and an optional algorithm sizeAlgorithm, perform the following steps. |writeAlgorithm| must be an algorithm that accepts a [=chunk=] object and returns a promise. If given, |closeAlgorithm| and |abortAlgorithm| may return a promise. If given, |sizeAlgorithm| must @@ -7034,14 +7034,22 @@ reason.
To set up a newly-[=new|created-via-Web IDL=] {{TransformStream}} |stream| given an algorithm transformAlgorithm and an optional algorithm flushAlgorithm, perform the following steps. + for="TransformStream/set up">transformAlgorithm, an optional algorithm flushAlgorithm, an optional number writableHighWaterMark (default 1), an optional + algorithm writableSizeAlgorithm, an + optional number readableHighWaterMark + (default 0), and an optional algorithm readableSizeAlgorithm, perform the following steps. |transformAlgorithm| and, if given, |flushAlgorithm|, may return a promise. + If given, |writableSizeAlgorithm| and |readableSizeAlgorithm| must be algorithms accepting + [=chunk=] objects and returning a number; and if given, |writableHighWaterMark| and + |readableHighWaterMark| must be non-negative, non-NaN numbers. - 1. Let |writableHighWaterMark| be 1. - 1. Let |writableSizeAlgorithm| be an algorithm that returns 1. - 1. Let |readableHighWaterMark| be 0. - 1. Let |readableSizeAlgorithm| be an algorithm that returns 1. + 1. If |writableSizeAlgorithm| was not given, let |writableSizeAlgorithm| be an algorithm that + returns 1. + 1. If |readableSizeAlgorithm| was not given, let |readableSizeAlgorithm| be an algorithm that + returns 1. 1. Let |transformAlgorithmWrapper| be an algorithm that runs these steps given a value |chunk|: 1. Let |result| be the result of running |transformAlgorithm| given |chunk|. If this throws an exception |e|, return [=a promise rejected with=] |e|. @@ -7086,7 +7094,7 @@ reason. The following algorithms must only be used on {{TransformStream}} instances initialized via the above [=TransformStream/set up=] algorithm. Usually they are called as part of [=TransformStream/set up/transformAlgorithm=] or -[=TransformStream/set up/flushAlgorithm=]. +[=TransformStream/set up/flushAlgorithm=].

To enqueue the JavaScript value |chunk| into a {{TransformStream}} |stream|, perform ! @@ -7129,8 +7137,7 @@ Including the {{GenericTransformStream}} mixin will give an IDL interface the ap the behavior of the resulting interface, its constructor (or other initialization code) must set each instance's [=GenericTransformStream/transform=] to a [=new=] {{TransformStream}}, and then [=TransformStream/set up|set it up=] with appropriate customizations via the -[=TransformStream/set up/transformAlgorithm=] and optionally -[=TransformStream/set up/flushAlgorithm=] arguments. +[=TransformStream/set up/transformAlgorithm=] and any optional arguments. Note: Existing examples of this pattern on the web platform include {{CompressionStream}} and {{TextDecoderStream}}. [[COMPRESSION]] [[ENCODING]] From 1eafb514565662e1807cdae67280c04e57eea9f1 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Tue, 30 Nov 2021 23:41:12 +0100 Subject: [PATCH 11/13] Set writable HWM to 0 in "create an identity TransformStream" --- index.bs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index d32921b2a..a90003494 100644 --- a/index.bs +++ b/index.bs @@ -7083,9 +7083,11 @@ reason. an identity {{TransformStream}}: 1. Let |transformStream| be a [=new=] {{TransformStream}}. + 1. Let |transformAlgorithm| be an algorithm which, given |chunk|, [=TransformStream/enqueues=] + |chunk| in |transformStream|. 1. [=TransformStream/Set up=] |transformStream| with [=TransformStream/set up/transformAlgorithm=] set to an algorithm which, given - |chunk|, [=TransformStream/enqueues=] |chunk| in |transformStream|. + ignore>[=TransformStream/set up/transformAlgorithm=] set to |transformAlgorithm| and [=TransformStream/set up/writableHighWaterMark=] set to 0. 1. Return |transformStream|.

From 976492b06e06fd574cfeae443e73ccdc4a25c9e7 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Wed, 1 Dec 2021 22:52:07 +0100 Subject: [PATCH 12/13] Remove custom ID for new abstract op --- index.bs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.bs b/index.bs index a90003494..8ca3160b7 100644 --- a/index.bs +++ b/index.bs @@ -5314,8 +5314,7 @@ The following abstract operations support the implementation of the
- WritableStreamDefaultControllerReleaseBackpressure(|controller|) + WritableStreamDefaultControllerReleaseBackpressure(|controller|) performs the following steps: 1. Let |stream| be |controller|.[=WritableStreamDefaultController/[[stream]]=]. From 89292d394dd4772d3e3dc382da3b6d88c9fc54ba Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Wed, 1 Dec 2021 22:52:14 +0100 Subject: [PATCH 13/13] Add missing ! --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 8ca3160b7..471d7d772 100644 --- a/index.bs +++ b/index.bs @@ -5321,7 +5321,7 @@ The following abstract operations support the implementation of the 1. Assert: |stream|.[=WritableStream/[[state]]=] is "`writable`". 1. Set |controller|.[=WritableStreamDefaultController/[[releaseBackpressure]]=] to true. 1. If ! [$WritableStreamHasOperationMarkedInFlight$](|stream|) is false and - [$WritableStreamCloseQueuedOrInFlight$](|stream|) is false, + ! [$WritableStreamCloseQueuedOrInFlight$](|stream|) is false, 1. Let |backpressure| be ! [$WritableStreamDefaultControllerGetBackpressure$](|controller|). 1. Perform ! [$WritableStreamUpdateBackpressure$](|stream|, |backpressure|).