Skip to content

Commit

Permalink
internal/gcsfs: hide OS files until Close
Browse files Browse the repository at this point in the history
GCS doesn't show you in-progress files, and I wrote various await
functions under that assumption. The local filesystem didn't match that
behavior, which led to empty files being read.

Emulate GCS by writing to a hidden temp file that's renamed to the real
name upon Close.

Fixes golang/go#53972. (I hope.)

Change-Id: I34ec484128e417c4b9f6c7d0731df5fdabac652b
Reviewed-on: https://go-review.googlesource.com/c/build/+/429275
Run-TryBot: Heschi Kreinick <[email protected]>
Reviewed-by: Jenny Rakoczy <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Auto-Submit: Heschi Kreinick <[email protected]>
  • Loading branch information
heschi authored and gopherbot committed Sep 7, 2022
1 parent b9d22d5 commit 868cf67
Showing 1 changed file with 26 additions and 2 deletions.
28 changes: 26 additions & 2 deletions internal/gcsfs/osfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,35 @@ func (dir dirFS) Create(name string) (WriteFile, error) {
if err := os.MkdirAll(path.Dir(fullName), 0700); err != nil {
return nil, err
}
f, err := os.Create(fullName)

// GCS doesn't let you see a file until you're done writing it. Write
// to a temp file, which will be renamed to the expected name on Close.
temp, err := os.CreateTemp(path.Dir(fullName), "."+path.Base(fullName)+".writing-*")
if err != nil {
return nil, err
}
return f, nil
finalize := func() error {
return os.Rename(temp.Name(), fullName)
}
return &writingFile{temp, finalize}, nil
}

type writingFile struct {
*os.File
finalize func() error
}

func (wf *writingFile) Close() error {
if err := wf.File.Close(); err != nil {
return err
}
if wf.finalize != nil {
if err := wf.finalize(); err != nil {
return err
}
wf.finalize = nil
}
return nil
}

func (dir dirFS) Sub(subDir string) (fs.FS, error) {
Expand Down

0 comments on commit 868cf67

Please sign in to comment.