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

Add drive.rename(oldPath, newPath) #376

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

lejeunerenard
Copy link

Only updates the file entry in the hyperbee.

This PR was inspired by someone wanting to rename the file without having to re-append the blobstore entry.

@lejeunerenard
Copy link
Author

Addresses #364. Should this renaming happen as a batch append? I had assumed that if batching was required, it could be done at the drive level instead, aka:

const b = drive.batch()
await b.rename(oldPath, newPath)
await b.flush()

@serapath
Copy link

serapath commented Oct 8, 2024

@HDegroote any chance this could be merged? Maybe even soon? :-)

index.js Outdated
async rename (oldPath, newPath, opts) {
const existingEntry = await this.entry(oldPath, opts)
await this.db.del(std(oldPath, false), { keyEncoding })
return this.db.put(std(newPath, false), existingEntry.value, { keyEncoding })
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic is prone to race conditions:

  • If the process crashes/stops after doing the del, but before the put runs, the entry's metadata no longer exists
  • if rename runs twice for the same oldPath and newPath, and the second one starts after the first one finished its del operation (but before it finished its put), then existingEntry will be null, so the second run will override the result of the first one and make it point to null

The first issue can be resolved by using a batch, and the second with some sort of lock or debounce, but I'm not sure it's worth the complexity for this feature

Copy link
Author

Choose a reason for hiding this comment

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

Great catch! I should have thought of this.
Added drive.batch() to lock the drive while renaming which should address the race condition and the mid process crash concern.

@HDegroote
Copy link
Contributor

@HDegroote any chance this could be merged? Maybe even soon? :-)

It's @mafintosh who decides on merging PR's for Hyperdrive, so best to ping him.

I reviewed the PR though. I think it's a less trivial feature than you initially thought, because of the potential for race conditions.

@mafintosh
Copy link
Contributor

Needs a batch, no need for extra lock. The read should be on the batch as well. Docs need to specify that its for a single entry also

Only updates the file entry in the hyperbee.
Previously renaming an entry twice at the same time could result in a
race condition where the two entries were created for the same `oldPath`
etc.
@lejeunerenard
Copy link
Author

Specified that rename() applies to one entry and added a test to prove that renaming works on symlinks as well as blob entries.

@serapath
Copy link

just wanted to come back and wonder if rename could be done using .batch to see further work has happened and it might work now?

The idea was to create a method .rename that just internally uses batch with all operations required to make rename work.

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.

4 participants