summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2024-04-08 12:47:34 +0900
committerGitHub <noreply@github.com>2024-04-08 12:47:34 +0900
commit2670c1d580320ed01d3a7add27bc5db2a23ac80b (patch)
tree0bad7c76feaaa06c88cc42cafb8d7689a8e0f199
parent49f6e2e79e66fe2c456e8745e86cfd148a748c9d (diff)
fix(ext/node): out-of-order writes of fs.createWriteStream (#23244)
This PR follows this fix (https://github.com/nodejs/node/pull/52005) in Node.js. Stream's construct callback happens one tick earlier by this change, and it prevents the reordering of the first few chunks in `node:stream.Writable` closes #20284
-rw-r--r--ext/node/polyfills/_stream.mjs5
-rw-r--r--tests/unit_node/fs_test.ts35
2 files changed, 36 insertions, 4 deletions
diff --git a/ext/node/polyfills/_stream.mjs b/ext/node/polyfills/_stream.mjs
index 6b772ac04..591f8bb51 100644
--- a/ext/node/polyfills/_stream.mjs
+++ b/ext/node/polyfills/_stream.mjs
@@ -1665,7 +1665,7 @@ var require_destroy = __commonJS({
} else if (err) {
errorOrDestroy(stream, err, true);
} else {
- process.nextTick(emitConstructNT, stream);
+ stream.emit(kConstruct);
}
}
try {
@@ -1676,9 +1676,6 @@ var require_destroy = __commonJS({
nextTick(onConstruct, err);
}
}
- function emitConstructNT(stream) {
- stream.emit(kConstruct);
- }
function isRequest(stream) {
return stream && stream.setHeader && typeof stream.abort === "function";
}
diff --git a/tests/unit_node/fs_test.ts b/tests/unit_node/fs_test.ts
index caa266ef2..e62a246fa 100644
--- a/tests/unit_node/fs_test.ts
+++ b/tests/unit_node/fs_test.ts
@@ -5,6 +5,7 @@ import { join } from "node:path";
import { tmpdir } from "node:os";
import {
constants,
+ createWriteStream,
existsSync,
mkdtempSync,
promises,
@@ -14,6 +15,7 @@ import {
writeFileSync,
} from "node:fs";
import { constants as fsPromiseConstants, cp } from "node:fs/promises";
+import process from "node:process";
import { pathToAbsoluteFileUrl } from "../unit/test_util.ts";
Deno.test(
@@ -121,3 +123,36 @@ Deno.test(
assert(dataRead === "Hello");
},
);
+
+// TODO(kt3k): Delete this test case, and instead enable the compat case
+// `test/parallel/test-fs-writestream-open-write.js`, when we update
+// `tests/node_compat/runner/suite`.
+Deno.test("[node/fs createWriteStream", async () => {
+ const { promise, resolve, reject } = Promise.withResolvers<void>();
+ const tempDir = await Deno.makeTempDir();
+ const file = join(tempDir, "file.txt");
+ try {
+ const w = createWriteStream(file);
+
+ w.on("open", () => {
+ w.write("hello, ");
+
+ process.nextTick(() => {
+ w.write("world");
+ w.end();
+ });
+ });
+
+ w.on("close", async () => {
+ try {
+ assertEquals(await Deno.readTextFile(file), "hello, world");
+ resolve();
+ } catch (e) {
+ reject(e);
+ }
+ });
+ await promise;
+ } finally {
+ await Deno.remove(tempDir, { recursive: true });
+ }
+});