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

fs: inconsistent options treatment between rm() and rmdir() #35689

Open
Trott opened this issue Oct 16, 2020 · 6 comments
Open

fs: inconsistent options treatment between rm() and rmdir() #35689

Trott opened this issue Oct 16, 2020 · 6 comments
Labels
fs Issues and PRs related to the fs subsystem / file system.

Comments

@Trott
Copy link
Member

Trott commented Oct 16, 2020

  • Version: 14.14.0 and 15.0.0-pre (master branch)
  • Platform: macOS
  • Subsystem: fs

What steps will reproduce the bug?

Use /dev/null as the path like below, or use some other path that will not be removed and force a retry.

This tries, doesn't remove /dev/null, and exits with "done" very quickly.

$ node -e 'fs.rmdir("/dev/null", { maxRetries: 42 }, () => { console.log("done"); })'

So does this:

$ node -e 'fs.rmdir("/dev/null", { maxRetries: 420 }, () => { console.log("done"); })'

This does the same:

$ node -e 'fs.rm("/dev/null", { maxRetries: 1 }, () => { console.log("done"); })'

But this takes about 90 seconds to finish, presumably because it is respecting the maxRetries option (with a backoff, I imagine) whereas fs.rmdir() ignores it if recursive is not set:

$ node -e 'fs.rm("/dev/null", { maxRetries: 42 }, () => { console.log("done"); })'

How often does it reproduce? Is there a required condition?

Reproduces every time.

What is the expected behavior?

I would expect fs.rm() and fs.rmdir() to treat maxRetries the same.

What do you see instead?

fs.rm() honors it with or without recursive being set, whereas fs.rmdir() ignores it unless recursive is set.

Additional information

@Trott
Copy link
Member Author

Trott commented Oct 16, 2020

@iansu @bcoe @cjihrig @nodejs/fs I think the right thing to do here is for both methods to honor maxRetries without recursive set. As a user, that's what I would expect. But I want to make sure there's agreement on that. WDYT?

@Trott Trott added the fs Issues and PRs related to the fs subsystem / file system. label Oct 16, 2020
@iansu
Copy link
Contributor

iansu commented Oct 16, 2020

I agree that they should both treat maxRetries the same but I'm not sure that they should respect that option if recursive has not been set. maxRetries is a rimraf option. If you're calling rmdir without recursive then it won't use rimraf at all so the option doesn't really make sense and shouldn't have any effect.

In your example it also seems strange that fs.rmdir, when pointed at a file without the recursive option doesn't produce an error. I can take a closer look into what's going on here.

@Trott
Copy link
Member Author

Trott commented Oct 17, 2020

In your example it also seems strange that fs.rmdir, when pointed at a file without the recursive option doesn't produce an error. I can take a closer look into what's going on here.

It produces an error, but my callback swallows it.

@Trott
Copy link
Member Author

Trott commented Oct 17, 2020

I agree that they should both treat maxRetries the same but I'm not sure that they should respect that option if recursive has not been set. maxRetries is a rimraf option. If you're calling rmdir without recursive then it won't use rimraf at all so the option doesn't really make sense and shouldn't have any effect.

For non-recursive calls, I wonder if retries still make sense when dealing with NFS, for example.

@IgorHalfeld
Copy link

For non-recursive calls, I wonder if retries still make sense when dealing with NFS, for example.

I think it makes sense, not having a file inside is not the only reason for an unsuccessful deletion, it would be nice to have maxRetries in this case too 🤔

@bcoe
Copy link
Contributor

bcoe commented Oct 20, 2020

I think the right thing to do here is for both methods to honor maxRetries without recursive set

maxRetries was added at some point to allow folks to pass this option to the rimraf.js. The reason for the option is that Windows has race conditions when deleting all files in a folder, so it's common to need to attempt the removal a few times.

I think maxRetries should be a noop if not used in conjunction with recursive, probably with a warning.


I don't hold this opinion particularly strongly, I just can't see retries being as useful outside the context of rimraf.js.

Edit: it's called maxBusyTries in rimraf, but I think it does the same thing.

@bcoe bcoe mentioned this issue Oct 20, 2020
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

No branches or pull requests

4 participants