-
-
Notifications
You must be signed in to change notification settings - Fork 252
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
Rimraf version 4, first pass #229
Conversation
0970a08
to
71067e7
Compare
1 similar comment
fb34aec
to
a03ce56
Compare
So.... the move-then-remove approach is about 2x to 10x slower on Windows (for all of the shallow-broad, deep-narrow, and mid-mid folder tree structures I tested, whether the dirs contained a mix of folders and files, all files, or all folders). Also, I can't get the EBUSY/ENOTEMPTY errors to trigger using the posix approach on Windows. (The good news is that the posix approach is comparably performant as the native approach, on macos linux and windows, so that's validating.) So I think the way forward here is:
|
Reference to the way that Microsoft's own tools remove directories: https://github.com/microsoft/BuildXL/blob/3508b0d6c4dea5ad53cdeba53819a2b3024e67e5/Public/Src/Utilities/Native/IO/Windows/FileUtilities.Win.cs#L165 |
Is there any progress on this pr? |
I'd love to have this thing released. Not having any dependencies sounds very good and it's part of the PR :D |
Well, quite a long time coming, eh? Refactored the windows strategy so that it does a normal naive recursive rm, but first deleting all files, then all folders, and falling back to move-then-remove only when it encounters an error indicating that a file is taking too long to remove from a directory. (Doing move-then-remove in all cases is wayyyyy too slow.) Also, the windows approach uses exponential backoff (or merely retries in the sync case) to handle EBUSY, ENFILE, and EMFILE errors. This mirrors the strategy used by the Microsoft brand tools that I could find source code for. In the simple async case, performance is comparable to the posix recursive rm (meaning, better than Node's builtin for the async case, and only slightly worse for the sync case). Only thing lacking is tests for retry-busy.js, and I should probably add a .d.ts file for it. |
This works around the occasional slowness observed in fs.promises methods, as well as providing a polyfill for node v10, while also avoiding the warning about the fs/promises API being experimental on that version.
Otherwise we get a coverage line missing
Try to avoid the situation where this approach: rimraf(path).then(() => rimraf(dirname(path)) fails with EBUSY, due to the semi-presence of marked-for-deletion entries.
When preserveRoot is set to false, we may remove all the children of the root directory, but we'll never actually succeed in rmdir()-ing the root dir itself, so don't try.
Add a `npm run benchmark` script.
It looks like I can't kick off the benchmark workflow until it's merged in, but seems to be showing favorable results locally on windows and macOS, so I'm gonna land it. |
Remaining todo:
rm -rf
subprocess, rimraf v3, and native, but in a way that doesn't just pick a winner at random 😬Drop support for node v10, orhandle the lack offs.promises
Provide custom fs functions? Idk, does anyone really need that feature?Dropping it for now. It's easy to bring back if it's an issue, but if no one requests it, better to not have the added complexity.