github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/store/cache/cache.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/store/cache/cache.go 14 15 package cache 16 17 import ( 18 "github.com/tickoalcantara12/micro/v3/service/store" 19 "github.com/tickoalcantara12/micro/v3/service/store/memory" 20 ) 21 22 // cache store is a store with caching to reduce IO where applicable. 23 // A memory store is used to cache reads from the given backing store. 24 // Reads are read through, writes are write-through 25 type cache struct { 26 m store.Store // the memory store 27 b store.Store // the backing store, could be file, cockroach etc 28 options store.Options 29 } 30 31 // NewStore returns a new cache store 32 func NewStore(store store.Store, opts ...store.Option) store.Store { 33 cf := &cache{ 34 m: memory.NewStore(opts...), 35 b: store, 36 } 37 return cf 38 39 } 40 41 func (c *cache) init(opts ...store.Option) error { 42 for _, o := range opts { 43 o(&c.options) 44 } 45 return nil 46 } 47 48 // Init initialises the underlying stores 49 func (c *cache) Init(opts ...store.Option) error { 50 if err := c.init(opts...); err != nil { 51 return err 52 } 53 if err := c.m.Init(opts...); err != nil { 54 return err 55 } 56 return c.b.Init(opts...) 57 } 58 59 // Options allows you to view the current options. 60 func (c *cache) Options() store.Options { 61 return c.options 62 } 63 64 // Read takes a single key name and optional ReadOptions. It returns matching []*Record or an error. 65 func (c *cache) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) { 66 recs, err := c.m.Read(key, opts...) 67 if err != nil && err != store.ErrNotFound { 68 return nil, err 69 } 70 if len(recs) > 0 { 71 return recs, nil 72 } 73 recs, err = c.b.Read(key, opts...) 74 if err == nil { 75 for _, rec := range recs { 76 if err := c.m.Write(rec); err != nil { 77 return nil, err 78 } 79 } 80 } 81 return recs, err 82 } 83 84 // Write() writes a record to the store, and returns an error if the record was not written. 85 // If the write succeeds in writing to memory but fails to write through to file, you'll receive an error 86 // but the value may still reside in memory so appropriate action should be taken. 87 func (c *cache) Write(r *store.Record, opts ...store.WriteOption) error { 88 if err := c.m.Write(r, opts...); err != nil { 89 return err 90 } 91 return c.b.Write(r, opts...) 92 } 93 94 // Delete removes the record with the corresponding key from the store. 95 // If the delete succeeds in writing to memory but fails to write through to file, you'll receive an error 96 // but the value may still reside in memory so appropriate action should be taken. 97 func (c *cache) Delete(key string, opts ...store.DeleteOption) error { 98 if err := c.m.Delete(key, opts...); err != nil { 99 return err 100 } 101 return c.b.Delete(key, opts...) 102 } 103 104 // List returns any keys that match, or an empty list with no error if none matched. 105 func (c *cache) List(opts ...store.ListOption) ([]string, error) { 106 keys, err := c.m.List(opts...) 107 if err != nil && err != store.ErrNotFound { 108 return nil, err 109 } 110 if len(keys) > 0 { 111 return keys, nil 112 } 113 keys, err = c.b.List(opts...) 114 if err == nil { 115 for _, key := range keys { 116 recs, err := c.b.Read(key) 117 if err != nil { 118 return nil, err 119 } 120 for _, r := range recs { 121 if err := c.m.Write(r); err != nil { 122 return nil, err 123 } 124 } 125 126 } 127 } 128 return keys, err 129 } 130 131 // Close the store and the underlying store 132 func (c *cache) Close() error { 133 if err := c.m.Close(); err != nil { 134 return err 135 } 136 return c.b.Close() 137 } 138 139 // String returns the name of the implementation. 140 func (c *cache) String() string { 141 return "cache" 142 }