func (g *GCSBackend) Delete(key string) error {
	defer metrics.MeasureSince([]string{"gcs", "delete"}, time.Now())
	bucket := g.client.Bucket(g.bucketName)
	g.permitPool.Acquire()
	defer g.permitPool.Release()
	err := bucket.Object(key).Delete(context.Background())
	if err == storage.ErrObjectNotExist {
		return nil
	} else if err != nil {
		return fmt.Errorf("error deleting object '%v': '%v'", key, err)
	}
	return nil
}
Delete is used to permanently delete an entry
package physical
import (
	"fmt"
	"io/ioutil"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
	"github.com/hashicorp/errwrap"
	log "github.com/mgutz/logxi/v1"
	"cloud.google.com/go/storage"
	"github.com/armon/go-metrics"
	"golang.org/x/net/context"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
)
type GCSBackend struct {
	bucketName string
	client     *storage.Client
	permitPool *PermitPool
	logger     log.Logger
}
func newGCSBackend(conf map[string]string, logger log.Logger) (Backend, error) {
	bucketName := os.Getenv("GOOGLE_STORAGE_BUCKET")
	if bucketName == "" {
		bucketName = conf["bucket"]
		if bucketName == "" {
			return nil, fmt.Errorf("env var GOOGLE_STORAGE_BUCKET or configuration parameter 'bucket' must be set")
		}
	}
	credentialsFile := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
	if credentialsFile == "" {
		credentialsFile = conf["credentials_file"]
		if credentialsFile == "" {
			return nil, fmt.Errorf("env var GOOGLE_APPLICATION_CREDENTIALS or configuration parameter 'credentials_file' must be set")
		}
	}
	client, err := storage.NewClient(
		context.Background(),
		option.WithServiceAccountFile(credentialsFile),
	)
	if err != nil {
		return nil, fmt.Errorf("error establishing storage client: '%v'", err)
	}
	_, err = client.Bucket(bucketName).Attrs(context.Background())
	if err != nil {
		return nil, fmt.Errorf("unable to access bucket '%s': '%v'", bucketName, err)
	}
	maxParStr, ok := conf["max_parallel"]
	var maxParInt int
	if ok {
		maxParInt, err = strconv.Atoi(maxParStr)
		if err != nil {
			return nil, errwrap.Wrapf("failed parsing max_parallel parameter: {{err}}", err)
		}
		if logger.IsDebug() {
			logger.Debug("physical/gcs: max_parallel set", "max_parallel", maxParInt)
		}
	}
	g := GCSBackend{
		bucketName: bucketName,
		client:     client,
		permitPool: NewPermitPool(maxParInt),
		logger:     logger,
	}
	return &g, nil
}
func (g *GCSBackend) Put(entry *Entry) error {
	defer metrics.MeasureSince([]string{"gcs", "put"}, time.Now())
	bucket := g.client.Bucket(g.bucketName)
	writer := bucket.Object(entry.Key).NewWriter(context.Background())
	g.permitPool.Acquire()
	defer g.permitPool.Release()
	defer writer.Close()
	_, err := writer.Write(entry.Value)
	return err
}
func (g *GCSBackend) Get(key string) (*Entry, error) {
	defer metrics.MeasureSince([]string{"gcs", "get"}, time.Now())
	bucket := g.client.Bucket(g.bucketName)
	reader, err := bucket.Object(key).NewReader(context.Background())
	if err == storage.ErrObjectNotExist {
		return nil, nil
	} else if err != nil {
		return nil, fmt.Errorf("error creating bucket reader: '%v'", err)
	}
	g.permitPool.Acquire()
	defer g.permitPool.Release()
	defer reader.Close()
	value, err := ioutil.ReadAll(reader)
	if err != nil {
		return nil, fmt.Errorf("error reading object '%v': '%v'", key, err)
	}
	ent := Entry{
		Key:   key,
		Value: value,
	}
	return &ent, nil
}