Skip to content
This repository was archived by the owner on Jul 16, 2022. It is now read-only.

Comments

WIP Add AtomicFolder#36

Closed
sotte wants to merge 4 commits intountitaker:masterfrom
sotte:atomic_folder
Closed

WIP Add AtomicFolder#36
sotte wants to merge 4 commits intountitaker:masterfrom
sotte:atomic_folder

Conversation

@sotte
Copy link

@sotte sotte commented Aug 12, 2018

This is pretty much just copy&paste from one of my projects. Your version is much more sophisticated but I think it's good to have the code just to get the discussion started.

Things that have to be addressed:

  • rename_dont_move could be replaced by existing functionality.
  • Test on windows.
  • Adjust coding style
  • Update docs
  • Write tests
  • Anything else?

@untitaker what do you think?

I'll clean up the commit history once the PR is ready.

This PR closes #35.

Copy link
Owner

@untitaker untitaker left a comment

Choose a reason for hiding this comment

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

Regarding codestyle, I will eventually run black against the entire codebase, so don't worry too much about it.




###############################################################################
Copy link
Owner

Choose a reason for hiding this comment

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

If this is necessary I think it's time to start a new file! Please create a file folders.py and import AtomicFolder from it.

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I'll do that once the content is fine!

"""
if os.path.isdir(dst):
raise FolderAlreadyExists("'{}' already exists".format(dst))
shutil.move(path, dst)
Copy link
Owner

@untitaker untitaker Aug 12, 2018

Choose a reason for hiding this comment

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

This function is not atomic as the implementation in luigi notes in its warning message. Here is a race condition for example: We have two processes A and B, which both run this function.

  • Process A runs isdir, which returns false
  • Process B runs isdir, which returns false
  • Process A moves its tmpdir to the target path
  • Process B moves its tmpdir to the target path (or rather, into the directory created by A)

I am not sure whether we can guarantee to fail atomically if the target path doesn't exist. If you have any ideas regarding that... Ideally we would have an overwrite param but I am not sure if that is possible.

class FolderAlreadyExists(Exception): pass


class AtomicFolder():
Copy link
Owner

Choose a reason for hiding this comment

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

Please model AtomicFolder like the API of AtomicWriter for consistency, concretely that it itself is not a contextmanager but rather has a open() method that returns a context manager, and separate methods for commit and rollback.

Copy link
Owner

Choose a reason for hiding this comment

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

Oh and please subclass from object such that we have a newstyle class on both Python 2 and 3.

@untitaker
Copy link
Owner

See discussion on #35

@untitaker untitaker closed this Dec 16, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add atomic_folder

2 participants