Skip to content

Commit b3f4d63

Browse files
authored
fix(storage): honor --enable-rapid-writes flag during object overwrites for pirlo buckets (#5004)
1 parent 1c99530 commit b3f4d63

2 files changed

Lines changed: 34 additions & 14 deletions

File tree

internal/storage/bucket_handle.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,29 @@ func (bh *bucketHandle) getObjectHandleWithPreconditionsSet(req *gcs.CreateObjec
193193
return obj
194194
}
195195

196+
func (bh *bucketHandle) getStorageClassForCreateObject(defaultStorageClass string) string {
197+
// When rapid writes are enabled on an RCU bucket, objects should be explicitly
198+
// created with the RAPID storage class in the zonal cache rather than
199+
// defaulting to the bucket's default storage class.
200+
// If rapid writes are disabled, we explicitly clear the storage class to prevent
201+
// inheriting the RAPID storage class from an overwritten object and write it to
202+
// the bucket's default storage class.
203+
switch bh.BucketType().Pirlo {
204+
case gcs.PirloStateRapidWritesEnabled:
205+
return storageClassRapid
206+
case gcs.PirloStateRapidWritesDisabled:
207+
return ""
208+
default:
209+
return defaultStorageClass
210+
}
211+
}
212+
196213
func (bh *bucketHandle) CreateObject(ctx context.Context, req *gcs.CreateObjectRequest) (o *gcs.Object, err error) {
197214
defer func() {
198215
err = gcs.GetGCSError(err)
199216
}()
200217

201-
// When rapid writes are enabled on an RCU bucket, objects should be explicitly
202-
// created with the RAPID storage class in the zonal cache rather than
203-
// defaulting to the bucket's default storage class
204-
if bh.BucketType().Pirlo == gcs.PirloStateRapidWritesEnabled {
205-
req.StorageClass = storageClassRapid
206-
}
218+
req.StorageClass = bh.getStorageClassForCreateObject(req.StorageClass)
207219

208220
obj := bh.getObjectHandleWithPreconditionsSet(req)
209221

@@ -247,12 +259,7 @@ func (bh *bucketHandle) CreateObject(ctx context.Context, req *gcs.CreateObjectR
247259
}
248260

249261
func (bh *bucketHandle) CreateObjectChunkWriter(ctx context.Context, req *gcs.CreateObjectRequest, chunkSize int, callBack func(bytesUploadedSoFar int64)) (gcs.Writer, error) {
250-
// When rapid writes are enabled on an RCU bucket, objects should be explicitly
251-
// created with the RAPID storage class in the zonal cache rather than
252-
// defaulting to the bucket's default storage class.
253-
if bh.BucketType().Pirlo == gcs.PirloStateRapidWritesEnabled {
254-
req.StorageClass = storageClassRapid
255-
}
262+
req.StorageClass = bh.getStorageClassForCreateObject(req.StorageClass)
256263

257264
obj := bh.getObjectHandleWithPreconditionsSet(req)
258265

internal/storage/bucket_handle_test.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,32 +688,45 @@ func (testSuite *BucketHandleTest) TestBucketHandle_StorageClassOverrides() {
688688
bucketScenarios := []struct {
689689
name string
690690
bucketType gcs.BucketType
691+
initialStorageClass string
691692
expectedWriterStorageClass string
692693
expectedCreatedStorageClass string
693694
canTestCreateObject bool
694695
}{
695696
{
696697
name: "StandardBucket",
697698
bucketType: gcs.BucketType{Pirlo: gcs.PirloStateNone},
699+
initialStorageClass: "",
698700
expectedWriterStorageClass: "",
699701
expectedCreatedStorageClass: "STANDARD",
700702
canTestCreateObject: true,
701703
},
704+
{
705+
name: "StandardBucket_InheritsStorageClass",
706+
bucketType: gcs.BucketType{Pirlo: gcs.PirloStateNone},
707+
initialStorageClass: "COLDLINE",
708+
expectedWriterStorageClass: "COLDLINE",
709+
expectedCreatedStorageClass: "COLDLINE",
710+
canTestCreateObject: true,
711+
},
702712
{
703713
name: "ZonalBucket",
704714
bucketType: gcs.BucketType{Zonal: true},
715+
initialStorageClass: "",
705716
expectedWriterStorageClass: "", // Zonal buckets do not use the RAPID storage class.
706717
canTestCreateObject: false, // Fails on HTTP append.
707718
},
708719
{
709720
name: "PirloBucket_RapidEnabled",
710721
bucketType: gcs.BucketType{Pirlo: gcs.PirloStateRapidWritesEnabled},
722+
initialStorageClass: "STANDARD", // Simulate inheriting from standard source
711723
expectedWriterStorageClass: storageClassRapid,
712724
canTestCreateObject: false, // Fails on HTTP append.
713725
},
714726
{
715727
name: "PirloBucket_RapidDisabled",
716728
bucketType: gcs.BucketType{Pirlo: gcs.PirloStateRapidWritesDisabled},
729+
initialStorageClass: storageClassRapid, // Simulate inheriting from rapid source
717730
expectedWriterStorageClass: "",
718731
expectedCreatedStorageClass: "STANDARD",
719732
canTestCreateObject: true,
@@ -725,7 +738,7 @@ func (testSuite *BucketHandleTest) TestBucketHandle_StorageClassOverrides() {
725738
createBucketHandle(testSuite, &controlpb.StorageLayout{})
726739
testSuite.bucketHandle.bucketType = &scenario.bucketType
727740
testSuite.bucketHandle.writeConfig = &cfg.WriteConfig{}
728-
req := &gcs.CreateObjectRequest{Name: "test_object_2"}
741+
req := &gcs.CreateObjectRequest{Name: "test_object_2", StorageClass: scenario.initialStorageClass}
729742

730743
w, err := testSuite.bucketHandle.CreateObjectChunkWriter(context.Background(), req, 1024, nil)
731744

@@ -740,7 +753,7 @@ func (testSuite *BucketHandleTest) TestBucketHandle_StorageClassOverrides() {
740753
createBucketHandle(testSuite, &controlpb.StorageLayout{})
741754
testSuite.bucketHandle.bucketType = &scenario.bucketType
742755
testSuite.bucketHandle.writeConfig = &cfg.WriteConfig{}
743-
req := &gcs.CreateObjectRequest{Name: "test_object_1", Contents: strings.NewReader("data")}
756+
req := &gcs.CreateObjectRequest{Name: "test_object_1", Contents: strings.NewReader("data"), StorageClass: scenario.initialStorageClass}
744757

745758
o, err := testSuite.bucketHandle.CreateObject(context.Background(), req)
746759

0 commit comments

Comments
 (0)