summaryrefslogtreecommitdiff
path: root/ext/web/06_streams.js
diff options
context:
space:
mode:
authorMarcos Casagrande <marcoscvp90@gmail.com>2022-10-24 13:13:20 +0200
committerGitHub <noreply@github.com>2022-10-24 13:13:20 +0200
commitb7d86b4bedbac8d7a200c36e7a63855210887ac4 (patch)
treef275bc4083f21626252f7d6f5b8bab3a06181e26 /ext/web/06_streams.js
parent873a5ce2eddb65cdfea7fc8bbcae3e8dfef5dfb9 (diff)
perf(ext/streams): fast path when consuming body of tee'd stream (#16329)
Add a fast path for consuming the body of cloned `Request`/`Response`, which is very common specially when using `cache` API.
Diffstat (limited to 'ext/web/06_streams.js')
-rw-r--r--ext/web/06_streams.js27
1 files changed, 27 insertions, 0 deletions
diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js
index c783b9518..52488efb6 100644
--- a/ext/web/06_streams.js
+++ b/ext/web/06_streams.js
@@ -652,6 +652,9 @@
const RESOURCE_REGISTRY = new FinalizationRegistry((rid) => {
core.tryClose(rid);
});
+
+ const _readAll = Symbol("[[readAll]]");
+ const _original = Symbol("[[original]]");
/**
* Create a new ReadableStream object that is backed by a Resource that
* implements `Resource::read_return`. This object contains enough metadata to
@@ -681,6 +684,17 @@
async pull(controller) {
const v = controller.byobRequest.view;
try {
+ if (controller[_readAll] === true) {
+ // fast path for tee'd streams consuming body
+ const chunk = await core.readAll(rid);
+ if (chunk.byteLength > 0) {
+ controller.enqueue(chunk);
+ }
+ controller.close();
+ tryClose();
+ return;
+ }
+
const bytesRead = await core.read(rid, v);
if (bytesRead === 0) {
tryClose();
@@ -809,8 +823,17 @@
/** @type {Uint8Array[]} */
const chunks = [];
let totalLength = 0;
+
+ // tee'd stream
+ if (stream[_original]) {
+ // One of the branches is consuming the stream
+ // signal controller.pull that we can consume it in a single op
+ stream[_original][_controller][_readAll] = true;
+ }
+
while (true) {
const { value: chunk, done } = await reader.read();
+
if (done) break;
if (!ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk)) {
@@ -3029,6 +3052,10 @@
pull2Algorithm,
cancel2Algorithm,
);
+
+ branch1[_original] = stream;
+ branch2[_original] = stream;
+
forwardReaderError(reader);
return [branch1, branch2];
}