fix(streams): don't use shared buffer for iterateReader outputs (#2735)

This commit is contained in:
Yoshiya Hinosawa 2022-10-03 20:09:52 +09:00 committed by GitHub
parent b161285109
commit 16ca2a1930
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 2 deletions

View File

@ -494,8 +494,8 @@ export async function* iterateReader(
}, },
): AsyncIterableIterator<Uint8Array> { ): AsyncIterableIterator<Uint8Array> {
const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE;
const b = new Uint8Array(bufSize);
while (true) { while (true) {
const b = new Uint8Array(bufSize);
const result = await r.read(b); const result = await r.read(b);
if (result === null) { if (result === null) {
break; break;
@ -545,8 +545,8 @@ export function* iterateReaderSync(
}, },
): IterableIterator<Uint8Array> { ): IterableIterator<Uint8Array> {
const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE;
const b = new Uint8Array(bufSize);
while (true) { while (true) {
const b = new Uint8Array(bufSize);
const result = r.readSync(b); const result = r.readSync(b);
if (result === null) { if (result === null) {
break; break;

View File

@ -1,6 +1,7 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals, assertRejects } from "../testing/asserts.ts"; import { assert, assertEquals, assertRejects } from "../testing/asserts.ts";
import { delay } from "../async/delay.ts";
import { import {
copy, copy,
iterateReader, iterateReader,
@ -737,6 +738,17 @@ Deno.test("iterateReader", async () => {
assertEquals(totalSize, 12); assertEquals(totalSize, 12);
}); });
Deno.test("iterateReader works with slow consumer", async () => {
const a = new Uint8Array([97]);
const b = new Uint8Array([98]);
const iter = iterateReader(readerFromIterable([a, b]));
const promises = [];
for await (const bytes of iter) {
promises.push(delay(10).then(() => bytes));
}
assertEquals([a, b], await Promise.all(promises));
});
Deno.test("iterateReaderSync", () => { Deno.test("iterateReaderSync", () => {
// ref: https://github.com/denoland/deno/issues/2330 // ref: https://github.com/denoland/deno/issues/2330
const encoder = new TextEncoder(); const encoder = new TextEncoder();
@ -771,3 +783,25 @@ Deno.test("iterateReaderSync", () => {
assertEquals(totalSize, 12); assertEquals(totalSize, 12);
}); });
Deno.test("iterateReaderSync works with slow consumer", async () => {
const a = new Uint8Array([97]);
const b = new Uint8Array([98]);
const data = [a, b];
const readerSync = {
readSync(u8: Uint8Array) {
const bytes = data.shift();
if (bytes) {
u8.set(bytes);
return bytes.length;
}
return null;
},
};
const iter = iterateReaderSync(readerSync);
const promises = [];
for (const bytes of iter) {
promises.push(delay(10).then(() => bytes));
}
assertEquals([a, b], await Promise.all(promises));
});