func (b *backend) invalidate(ctx context.Context, key string) {
	switch key {
	case "config":
		b.ResetClient()
	}
}
invalidate resets the plugin. This is called when a key is updated via
replication.
package gcppca
import (
	"context"
	"sync"
	"time"
	"github.com/hashicorp/errwrap"
	"github.com/hashicorp/vault/sdk/framework"
	"github.com/hashicorp/vault/sdk/helper/useragent"
	"github.com/hashicorp/vault/sdk/logical"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/option"
	pcaapi "cloud.google.com/go/security/privateca/apiv1"
)
var (
	defaultClientLifetime = 30 * time.Minute
)
type backend struct {
	*framework.Backend
	pcaClient           *pcaapi.CertificateAuthorityClient
	pcaClientCreateTime time.Time
	pcaClientLifetime   time.Duration
	pcaClientLock       sync.RWMutex
	ctx       context.Context
	ctxCancel context.CancelFunc
	ctxLock   sync.Mutex
}
func Factory(ctx context.Context, c *logical.BackendConfig) (logical.Backend, error) {
	b := Backend()
	if err := b.Setup(ctx, c); err != nil {
		return nil, err
	}
	return b, nil
}
func Backend() *backend {
	var b backend
	b.pcaClientLifetime = defaultClientLifetime
	b.ctx, b.ctxCancel = context.WithCancel(context.Background())
	b.Backend = &framework.Backend{
		BackendType: logical.TypeLogical,
		Help: "The GCP CA secrets engine provides issuing and revoking GCP CA based " +
			"certificates.",
		Paths: []*framework.Path{
			b.pathConfig(),
			b.pathGenerateKey(),
			b.pathCSR(),
		},
		Invalidate: b.invalidate,
		Clean:      b.clean,
	}
	return &b
}
func (b *backend) clean(_ context.Context) {
	b.ctxLock.Lock()
	b.ctxCancel()
	b.ctxLock.Unlock()
}