Skip to content

Commit

Permalink
fix(ext/node): out-of-order writes of fs.createWriteStream (#23244)
Browse files Browse the repository at this point in the history
This PR follows this fix (nodejs/node#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
  • Loading branch information
kt3k authored Apr 8, 2024
1 parent 49f6e2e commit 2670c1d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
5 changes: 1 addition & 4 deletions ext/node/polyfills/_stream.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,7 @@ var require_destroy = __commonJS({
} else if (err) {
errorOrDestroy(stream, err, true);
} else {
process.nextTick(emitConstructNT, stream);
stream.emit(kConstruct);
}
}
try {
Expand All @@ -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";
}
Expand Down
35 changes: 35 additions & 0 deletions tests/unit_node/fs_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { join } from "node:path";
import { tmpdir } from "node:os";
import {
constants,
createWriteStream,
existsSync,
mkdtempSync,
promises,
Expand All @@ -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(
Expand Down Expand Up @@ -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 });
}
});

0 comments on commit 2670c1d

Please sign in to comment.