// Delete all objects from the supplied bucket. Results are undefined if the // bucket is being concurrently updated. func DeleteAllObjects( ctx context.Context, bucket gcs.Bucket) error { bundle := syncutil.NewBundle(ctx) // List all of the objects in the bucket. objects := make(chan *gcs.Object, 100) bundle.Add(func(ctx context.Context) error { defer close(objects) return ListPrefix(ctx, bucket, "", objects) }) // Strip everything but the name. objectNames := make(chan string, 10e3) bundle.Add(func(ctx context.Context) (err error) { defer close(objectNames) for o := range objects { select { case <-ctx.Done(): err = ctx.Err() return case objectNames <- o.Name: } } return }) // Delete the objects in parallel. const parallelism = 64 for i := 0; i < parallelism; i++ { bundle.Add(func(ctx context.Context) error { for objectName := range objectNames { err := bucket.DeleteObject( ctx, &gcs.DeleteObjectRequest{ Name: objectName, }) if err != nil { return err } } return nil }) } return bundle.Join() }
func garbageCollectOnce( ctx context.Context, tmpObjectPrefix string, bucket gcs.Bucket) (objectsDeleted uint64, err error) { const stalenessThreshold = 30 * time.Minute b := syncutil.NewBundle(ctx) // List all objects with the temporary prefix. objects := make(chan *gcs.Object, 100) b.Add(func(ctx context.Context) (err error) { defer close(objects) err = gcsutil.ListPrefix(ctx, bucket, tmpObjectPrefix, objects) if err != nil { err = fmt.Errorf("ListPrefix: %v", err) return } return }) // Filter to the names of objects that are stale. now := time.Now() staleNames := make(chan string, 100) b.Add(func(ctx context.Context) (err error) { defer close(staleNames) for o := range objects { if now.Sub(o.Updated) < stalenessThreshold { continue } select { case <-ctx.Done(): err = ctx.Err() return case staleNames <- o.Name: } } return }) // Delete those objects. b.Add(func(ctx context.Context) (err error) { for name := range staleNames { err = bucket.DeleteObject( ctx, &gcs.DeleteObjectRequest{ Name: name, }) if err != nil { err = fmt.Errorf("DeleteObject(%q): %v", name, err) return } atomic.AddUint64(&objectsDeleted, 1) } return }) err = b.Join() return }