func (c *ReplicaClient) DeleteGeneration(ctx context.Context, generation string) error {
	if err := c.Init(ctx); err != nil {
		return err
	} else if generation == "" {
		return fmt.Errorf("generation required")
	}
	prefix := path.Join(c.Path, "generations", generation) + "/"
	internal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, "LIST").Inc()
	for it := c.bkt.Objects(ctx, &storage.Query{Prefix: prefix}); ; {
		attrs, err := it.Next()
		if err == iterator.Done {
			break
		} else if err != nil {
			return err
		}
		if err := c.bkt.Object(attrs.Name).Delete(ctx); isNotExists(err) {
			continue
		} else if err != nil {
			return fmt.Errorf("cannot delete object %q: %w", attrs.Name, err)
		}
		internal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, "DELETE").Inc()
	}
	return nil
}
DeleteGeneration deletes all snapshots & WAL segments within a generation.
package gcs
import (
	"context"
	"fmt"
	"io"
	"os"
	"path"
	"strings"
	"sync"
	"time"
	"cloud.google.com/go/storage"
	"github.com/benbjohnson/litestream"
	"github.com/benbjohnson/litestream/internal"
	"google.golang.org/api/iterator"
)
const ReplicaClientType = "gcs"
var _ litestream.ReplicaClient = (*ReplicaClient)(nil)
type ReplicaClient struct {
	mu     sync.Mutex
	client *storage.Client        
	bkt    *storage.BucketHandle  
	Bucket string
	Path   string
}
func NewReplicaClient() *ReplicaClient {
	return &ReplicaClient{}
}
func (c *ReplicaClient) Type() string {
	return ReplicaClientType
}
func (c *ReplicaClient) Init(ctx context.Context) (err error) {
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.client != nil {
		return nil
	}
	if c.client, err = storage.NewClient(ctx); err != nil {
		return err
	}
	c.bkt = c.client.Bucket(c.Bucket)
	return nil
}
func (c *ReplicaClient) Generations(ctx context.Context) ([]string, error) {
	if err := c.Init(ctx); err != nil {
		return nil, err
	}
	query := &storage.Query{
		Delimiter: "/",
		Prefix:    path.Join(c.Path, "generations") + "/",
	}
	it := c.bkt.Objects(ctx, query)
	var generations []string
	for {
		attrs, err := it.Next()
		if err == iterator.Done {
			break
		} else if err != nil {
			return nil, err
		}
		name := path.Base(strings.TrimSuffix(attrs.Prefix, "/"))
		if !litestream.IsGenerationName(name) {
			continue
		}
		generations = append(generations, name)
	}
	return generations, nil
}