diff --git a/physical/cache.go b/physical/cache.go index f1b1365a3b66..fc44d091ffb4 100644 --- a/physical/cache.go +++ b/physical/cache.go @@ -1,7 +1,6 @@ package physical import ( - "fmt" "strings" "github.com/hashicorp/golang-lru" @@ -19,11 +18,16 @@ const ( // Vault are for policy objects so there is a large read reduction // by using a simple write-through cache. type Cache struct { - backend Backend - transactional Transactional - lru *lru.TwoQueueCache - locks []*locksutil.LockEntry - logger log.Logger + backend Backend + lru *lru.TwoQueueCache + locks []*locksutil.LockEntry + logger log.Logger +} + +// TransactionalCache is a Cache that wraps the physical that is transactional +type TransactionalCache struct { + *Cache + Transactional } // NewCache returns a physical cache of the given size. @@ -43,10 +47,14 @@ func NewCache(b Backend, size int, logger log.Logger) *Cache { logger: logger, } - if txnl, ok := c.backend.(Transactional); ok { - c.transactional = txnl - } + return c +} +func NewTransactionalCache(b Backend, size int, logger log.Logger) *TransactionalCache { + c := &TransactionalCache{ + Cache: NewCache(b, size, logger), + Transactional: b.(Transactional), + } return c } @@ -128,18 +136,14 @@ func (c *Cache) List(prefix string) ([]string, error) { return c.backend.List(prefix) } -func (c *Cache) Transaction(txns []TxnEntry) error { - if c.transactional == nil { - return fmt.Errorf("physical/cache: underlying backend does not support transactions") - } - +func (c *TransactionalCache) Transaction(txns []TxnEntry) error { // Lock the world for _, lock := range c.locks { lock.Lock() defer lock.Unlock() } - if err := c.transactional.Transaction(txns); err != nil { + if err := c.Transactional.Transaction(txns); err != nil { return err } diff --git a/vault/core.go b/vault/core.go index 861e568edb33..4756ccdf8a45 100644 --- a/vault/core.go +++ b/vault/core.go @@ -462,9 +462,14 @@ func NewCore(conf *CoreConfig) (*Core, error) { c.corsConfig = &CORSConfig{core: c} // Load CORS config and provide a value for the core field. + _, txnOK := conf.Physical.(physical.Transactional) // Wrap the physical backend in a cache layer if enabled and not already wrapped if _, isCache := conf.Physical.(*physical.Cache); !conf.DisableCache && !isCache { - c.physical = physical.NewCache(conf.Physical, conf.CacheSize, conf.Logger) + if txnOK { + c.physical = physical.NewTransactionalCache(conf.Physical, conf.CacheSize, conf.Logger) + } else { + c.physical = physical.NewCache(conf.Physical, conf.CacheSize, conf.Logger) + } } if !conf.DisableMlock {