Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(node/fs): improve compatibility of fs.ReadStream #2653

Merged
merged 22 commits into from
Sep 21, 2022

Conversation

PolarETech
Copy link
Contributor

@PolarETech PolarETech commented Sep 14, 2022

This is in regards to the comment on #2634 (review).

part of #911

Scope

This PR aims to address the followings:

  1. Make the implementation closer to Node
  2. Support fd, start, end, and fs options
  3. Pass the following tests
  • parallel/test-fs-empty-readStream.js
  • parallel/test-fs-read-stream-double-close.js
  • parallel/test-fs-read-stream-encoding.js
  • parallel/test-fs-read-stream-fd.js
  • parallel/test-fs-read-stream-inherit.js (*1)
  • parallel/test-fs-read-stream-patch-open.js
  • parallel/test-fs-read-stream-resume.js
  • parallel/test-fs-read-stream-throw-type-error.js

Out of Scope

After examination, I'd like to transfer the following test-related implementations to later Issues and PRs, as they are difficult to address or require a large implementation outside of ReadStream.

  • parallel/test-fs-read-stream-err.js (*1)
    • Overridden fs.read/close must be executed in the ReadStream. However, the default import of fs in the ReadStream module leads to circular dependencies, so it cannot be implemented in the same way as Node (9305a95). Any advice on how to resolve this would be appreciated.
  • parallel/test-fs-read-stream-fd-leak.js
    • Same as above. fs.open/close are overridden within the test.
  • parallel/test-fs-read-stream-file-handle.js
    • Requires FileHandle class for fs.promises.open. (Ref.)
  • parallel/test-fs-read-stream-pos.js (*2)
    • Performance issue with fs.writeFileSync() causing a false positive.
  • parallel/test-fs-read-stream.js (*1)
    • ReadStream module implementation is complete.
    • child_process.spawnSync is required within the test. (Waiting for PR 2637)
    • child_process.exec is required within the test. (Waiting for PR 2684)

References

https://github.com/nodejs/node/blob/main/lib/internal/fs/streams.js

Remarks

(*1)
"bufferSize" option is present in the following tests.

  • parallel/test-fs-read-stream-err.js
  • parallel/test-fs-read-stream-inherit.js
  • parallel/test-fs-read-stream.js

The option was removed in Node v0.9.12, and the current behavior of Node's ReadStream is to ignore it.
Therefore, "bufferSize" option has not been implemented, but consider it fine.

(*2)
The following test repeatedly reads data for 90 seconds.

  • parallel/test-fs-read-stream-pos.js

If no errors occur during the read, the assert is never triggered, and it seems to be the intent of the test.

Comment on lines 40 to 45
const readInterval = setInterval(() => {
if (stream) return;
if (!appended) return;

stream = fs.createReadStream(file, {
highWaterMark: hwm,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was failing about 10 / 30 of the time, but it seems to be a false positive.
If createReadStream() is executed before the append to the test file is completed, the "data" event will not be called and common.mustCallAtLeast() verification will fail.
It is most likely an I/O performance issue, not ReadStream. The performance of fs.writeFileSync() in Deno is about 5 or 6 times slower than in Node. (Confirmed with Deno 1.25.3 and Node.js v18.9.0 on my laptop)

To avoid the issue, I have modified the test to make sure that the append to the test file is complete before executing createReadStream().

Comment on lines 87 to 98
setTimeout(() => {
if (stream && !stream.destroyed) {
stream.on('close', () => {
assert(cur);
process.exit();
});
stream.destroy();
} else {
assert(cur);
process.exit();
});
stream.destroy();
} else {
process.exit();
}
}
}, 20);
Copy link
Contributor Author

@PolarETech PolarETech Sep 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small wait time has been added because common.mustCallAtLeast() verification may also fail if stream.destroy() is called and the stream is terminated in the middle.
And assert(cur) has been added to detect a case where the test terminates without ever reading any data as a failure.

@PolarETech PolarETech marked this pull request as ready for review September 21, 2022 15:09
@PolarETech
Copy link
Contributor Author

As commented in #discussion_r972879858 and #discussion_r972880948, I have modified the contents of test-fs-read-stream-pos.js.
If there are any problems, please let me know.

There is one error in ci / node, but it appears to be unrelated to the changes in this PR.

Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes mostly LGTM, and the CI is green. Would you mind backing out the test I commented on?

node/_tools/config.json Show resolved Hide resolved
@@ -33,6 +38,7 @@
"test-fs-append-file.js",
"test-fs-chmod-mask.js",
"test-fs-chmod.js",
"test-fs-read-stream-pos.js",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we should just not include this test for the time being. We can revisit it when the underlying issues are addressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your intention. The test has been removed. e459b0b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants