Skip to content

Commit

Permalink
Improve function for resiliency including syncing the filesystem afte…
Browse files Browse the repository at this point in the history
…r final write
  • Loading branch information
matthewmcneely committed Jan 14, 2025
1 parent 80fe254 commit 76ee539
Showing 1 changed file with 56 additions and 13 deletions.
69 changes: 56 additions & 13 deletions dgraphtest/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,32 +182,75 @@ func copyBinary(fromDir, toDir, version string) error {
}

func copy(src, dst string) error {
// Validate inputs
if src == "" || dst == "" {
return errors.New("source and destination paths cannot be empty")
}

// Check source file
sourceFileStat, err := os.Stat(src)
if err != nil {
return err
return errors.Wrapf(err, "failed to stat source file: %s", src)
}
if !sourceFileStat.Mode().IsRegular() {
return errors.Wrap(err, fmt.Sprintf("%s is not a regular file", src))
return errors.Errorf("%s is not a regular file", src)
}

source, err := os.Open(src)
srcStat, _ := source.Stat()
// Open source file
source, err := os.OpenFile(src, os.O_RDONLY, 0)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error while opening file [%s]", src))
return errors.Wrapf(err, "failed to open source file: %s", src)
}
defer func() {
if err := source.Close(); err != nil {
log.Printf("warning: failed to close source file: %v", err)
}
}()

// Create destination directory if it doesn't exist
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return errors.Wrapf(err, "failed to create destination directory: %s", filepath.Dir(dst))
}
defer source.Close()

destination, err := os.Create(dst)
// Create destination file
destination, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, sourceFileStat.Mode())
if err != nil {
return err
return errors.Wrapf(err, "failed to create destination file: %s", dst)
}
defer destination.Close()
defer func() {
if err := destination.Close(); err != nil {
log.Printf("warning: failed to close destination file: %v", err)
}
}()

if err := os.Chmod(dst, srcStat.Mode()); err != nil {
return err
// Use buffered I/O for better performance
buf := make([]byte, 1024*1024) // 1MB buffer
written, err := io.CopyBuffer(destination, source, buf)
if err != nil {
return errors.Wrap(err, "failed to copy file contents")
}
_, err = io.Copy(destination, source)
return err

// Verify file sizes match
if written != sourceFileStat.Size() {
return errors.Errorf("incomplete copy: wrote %d bytes, expected %d bytes", written, sourceFileStat.Size())
}

// Ensure data is flushed to disk
if err := destination.Sync(); err != nil {
return errors.Wrap(err, "failed to sync destination file")
}

// Verify the copy
destStat, err := os.Stat(dst)
if err != nil {
return errors.Wrapf(err, "failed to stat destination file: %s", dst)
}
if destStat.Size() != sourceFileStat.Size() {
return errors.Errorf("size mismatch after copy: source=%d bytes, destination=%d bytes",
sourceFileStat.Size(), destStat.Size())
}

return nil
}

// IsHigherVersion checks whether "higher" is the higher version compared to "lower"
Expand Down

0 comments on commit 76ee539

Please sign in to comment.