Skip to content

Commit a5c5786

Browse files
feat(s3-bucket): add configurable S3Object deletion batch size, set 1000 as default
* feat: add configurable s3 object deletion batch size * feat: update default batch size to 1000
1 parent bb287ea commit a5c5786

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

pkg/awsmod/batch.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const (
1515
// DefaultBatchSize is the batch size we initialize when constructing a batch delete client.
1616
// This value is used when calling DeleteObjects. This represents how many objects to delete
1717
// per DeleteObjects call.
18-
DefaultBatchSize = 100
18+
DefaultBatchSize = 1000
1919
)
2020

2121
// BatchError will contain the key and bucket of the object that failed to
@@ -227,12 +227,16 @@ type BatchDelete struct {
227227
// }); err != nil {
228228
// return err
229229
// }
230-
func NewBatchDeleteWithClient(s3client DeleteObjectsAPIClient, options ...func(*BatchDelete)) *BatchDelete {
230+
func NewBatchDeleteWithClient(s3client DeleteObjectsAPIClient, batchSize int, options ...func(*BatchDelete)) *BatchDelete {
231231
svc := &BatchDelete{
232232
Client: s3client,
233233
BatchSize: DefaultBatchSize,
234234
}
235235

236+
if batchSize != -1 {
237+
svc.BatchSize = batchSize
238+
}
239+
236240
for _, opt := range options {
237241
opt(svc)
238242
}
@@ -261,9 +265,10 @@ func NewBatchDeleteWithClient(s3client DeleteObjectsAPIClient, options ...func(*
261265
// }); err != nil {
262266
// return err
263267
// }
264-
func NewBatchDelete(c *aws.Config, options ...func(*BatchDelete)) *BatchDelete {
268+
func NewBatchDelete(c *aws.Config, batchSize int, options ...func(*BatchDelete)) *BatchDelete {
265269
s3client := s3.NewFromConfig(*c)
266-
return NewBatchDeleteWithClient(s3client, options...)
270+
271+
return NewBatchDeleteWithClient(s3client, batchSize, options...)
267272
}
268273

269274
// BatchDeleteObject is a wrapper object for calling the batch delete operation.

resources/s3-bucket.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ func (r *S3Bucket) RemoveAllVersions(ctx context.Context) error {
231231
}
232232

233233
iterator := newS3DeleteVersionListIterator(r.svc, params, setBypass)
234-
return awsmod.NewBatchDeleteWithClient(r.svc).Delete(ctx, iterator, opts...)
234+
batchSize := r.settings.GetInt("S3VersionDeleteBatchSize")
235+
return awsmod.NewBatchDeleteWithClient(r.svc, batchSize).Delete(ctx, iterator, opts...)
235236
}
236237

237238
func (r *S3Bucket) RemoveAllObjects(ctx context.Context) error {
@@ -248,7 +249,8 @@ func (r *S3Bucket) RemoveAllObjects(ctx context.Context) error {
248249
}
249250

250251
iterator := newS3ObjectDeleteListIterator(r.svc, params, setBypass)
251-
return awsmod.NewBatchDeleteWithClient(r.svc).Delete(ctx, iterator, opts...)
252+
batchSize := r.settings.GetInt("S3ObjectDeleteBatchSize")
253+
return awsmod.NewBatchDeleteWithClient(r.svc, batchSize).Delete(ctx, iterator, opts...)
252254
}
253255

254256
func (r *S3Bucket) Settings(settings *libsettings.Setting) {

resources/s3-bucket_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (suite *TestS3BucketSuite) TearDownSuite() {
104104
iterator := newS3DeleteVersionListIterator(suite.svc, &s3.ListObjectVersionsInput{
105105
Bucket: suite.bucket,
106106
}, true)
107-
if err := awsmod.NewBatchDeleteWithClient(suite.svc).Delete(context.TODO(), iterator, bypassGovernanceRetention); err != nil {
107+
if err := awsmod.NewBatchDeleteWithClient(suite.svc, -1).Delete(context.TODO(), iterator, bypassGovernanceRetention); err != nil {
108108
if !strings.Contains(err.Error(), "NoSuchBucket") {
109109
suite.T().Fatalf("failed to delete objects, %v", err)
110110
}
@@ -113,7 +113,7 @@ func (suite *TestS3BucketSuite) TearDownSuite() {
113113
iterator2 := newS3ObjectDeleteListIterator(suite.svc, &s3.ListObjectsV2Input{
114114
Bucket: suite.bucket,
115115
}, true)
116-
if err := awsmod.NewBatchDeleteWithClient(suite.svc).Delete(context.TODO(), iterator2, bypassGovernanceRetention); err != nil {
116+
if err := awsmod.NewBatchDeleteWithClient(suite.svc, -1).Delete(context.TODO(), iterator2, bypassGovernanceRetention); err != nil {
117117
if !strings.Contains(err.Error(), "NoSuchBucket") {
118118
suite.T().Fatalf("failed to delete objects, %v", err)
119119
}
@@ -178,10 +178,34 @@ func (suite *TestS3BucketBypassGovernanceSuite) TestS3BucketRemoveWithBypass() {
178178
assert.Nil(suite.T(), err)
179179
}
180180

181+
type TestS3BucketBatchSizeSuite struct {
182+
TestS3BucketSuite
183+
}
184+
185+
func (suite *TestS3BucketBatchSizeSuite) TestS3BucketRemoveWithNonDefaultBatchSize() {
186+
// Create the S3Bucket object
187+
bucket := &S3Bucket{
188+
svc: suite.svc,
189+
settings: &libsettings.Setting{
190+
"BypassGovernanceRetention": true,
191+
"S3ObjectDeleteBatchSize": 1000,
192+
},
193+
Name: suite.bucket,
194+
ObjectLock: s3types.ObjectLockEnabledEnabled,
195+
}
196+
197+
err := bucket.Remove(context.TODO())
198+
assert.Nil(suite.T(), err)
199+
}
200+
181201
func TestS3BucketObjectLock(t *testing.T) {
182202
suite.Run(t, new(TestS3BucketObjectLockSuite))
183203
}
184204

185205
func TestS3BucketBypassGovernance(t *testing.T) {
186206
suite.Run(t, new(TestS3BucketBypassGovernanceSuite))
187207
}
208+
209+
func TestS3BucketBatchSize(t *testing.T) {
210+
suite.Run(t, new(TestS3BucketBatchSizeSuite))
211+
}

0 commit comments

Comments
 (0)