Skip to content

Commit

Permalink
Handle null preconditions correctly and simplify gcs lib again (#8400)
Browse files Browse the repository at this point in the history
  • Loading branch information
tylerwilliams authored Feb 13, 2025
1 parent 63a3991 commit 7022bb0
Showing 1 changed file with 30 additions and 24 deletions.
54 changes: 30 additions & 24 deletions server/backends/blobstore/gcs/gcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,35 +200,37 @@ func (g *GCSBlobStore) BlobExists(ctx context.Context, blobName string) (bool, e
}
}

// isEmpty returns a boolean indicating if the set of preconditions is empty
// or not. If any have been set, false is returned, otherwise true.
func isEmpty(conds storage.Conditions) bool {
switch {
case conds.GenerationMatch != 0:
return false
case conds.GenerationNotMatch != 0:
return false
case conds.DoesNotExist:
return false
case conds.MetagenerationMatch != 0:
return false
case conds.MetagenerationNotMatch != 0:
return false
default:
return true
}
}

func (g *GCSBlobStore) ConditionalWriter(ctx context.Context, blobName string, conds storage.Conditions) (interfaces.CommittedWriteCloser, error) {
ctx, cancel := context.WithCancel(ctx)
bw := g.bucketHandle.Object(blobName).If(conds).NewWriter(ctx)

var zw io.WriteCloser
if g.compress {
zw = util.NewCompressWriter(bw)
var bw *storage.Writer
if isEmpty(conds) {
bw = g.bucketHandle.Object(blobName).NewWriter(ctx)
} else {
zw = bw
}
cwc := ioutil.NewCustomCommitWriteCloser(zw)
cwc.CommitFn = func(int64) error {
if compresserCloseErr := zw.Close(); compresserCloseErr != nil {
cancel() // Don't try to finish the commit op if Close() failed.
// Canceling the context closes the Writer, so don't call bw.Close().
return compresserCloseErr
}
return bw.Close()
}
cwc.CloseFn = func() error {
cancel()
return nil
bw = g.bucketHandle.Object(blobName).If(conds).NewWriter(ctx)
}
return cwc, nil
}

func (g *GCSBlobStore) Writer(ctx context.Context, blobName string) (interfaces.CommittedWriteCloser, error) {
ctx, cancel := context.WithCancel(ctx)
bw := g.bucketHandle.Object(blobName).NewWriter(ctx)
// See https://pkg.go.dev/cloud.google.com/go/storage#Writer
// Always disable buffering in the client for these writes.
bw.ChunkSize = 0

var zw io.WriteCloser
if g.compress {
Expand All @@ -252,6 +254,10 @@ func (g *GCSBlobStore) Writer(ctx context.Context, blobName string) (interfaces.
return cwc, nil
}

func (g *GCSBlobStore) Writer(ctx context.Context, blobName string) (interfaces.CommittedWriteCloser, error) {
return g.ConditionalWriter(ctx, blobName, storage.Conditions{})
}

type decompressingCloser struct {
io.ReadCloser
alwaysClose func() error
Expand Down

0 comments on commit 7022bb0

Please sign in to comment.