Repository navigation
Conversation
WriteToFiles only created the base output path before renaming temp files into their final destinations. When file_naming returned a path with a subdirectory component, the rename failed because the target directory never existed, silently dropping the written files. Fixes apache#21313
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
WriteToFilesfails to write output when thefile_namingfunction places the final file under a subdirectory ofpath(e.g.file_naming=lambda *args: "subdir/file.txt"). The write silently produces no files instead of raising, because the rename error is caught and only logged at debug level.Root Cause
_MoveTempFilesIntoFinalDestinationFn.process()insdks/python/apache_beam/io/fileio.pycallsFileSystems.mkdirs(self.path.get())before renaming temp files into their final location, but the actual rename targets areFileSystems.join(self.path.get(), final_file_name), wherefinal_file_namecomes from the user-suppliedfile_namingfunction and can itself contain a subdirectory. Only the basepathgets created, not the nested directory the final file actually lives in. On filesystems that require the destination directory to exist before a rename (e.g. the local filesystem, viaos.rename), this raises anIOError/BeamIOErrorthat's caught and logged at debug level, so the files are silently never written.Solution
Compute the final destination paths first, then create the parent directory of each unique final destination (via
FileSystems.split) before attempting the rename, instead of only creating the base path.Testing
test_write_to_nested_directory_destinationinsdks/python/apache_beam/io/fileio_test.py, using afile_namingfunction that nests output under asubdir/directory and asserting all records are read back.BeamAssertException: ... == [], missing elements [...], i.e. zero files were written to the subdirectory).pytest apache_beam/io/fileio_test.py::WriteFilesTest— 8 passed, 1 pre-existing skip, after the fix.pytest apache_beam/io/fileio_test.py(full file) — 45 passed, 2 pre-existing skips.yapf --diffclean on both changed Python files.Related Issue
Fixes #21313